diff --git a/.github/workflows/gcc.yml b/.github/workflows/gcc.yml
index 6ba8ef3295..1f6fa3afcd 100644
--- a/.github/workflows/gcc.yml
+++ b/.github/workflows/gcc.yml
@@ -15,9 +15,9 @@ env:
# The jobs are split into:
# 1. a dependency build step (setup), and
-# 2. a GSI build step (build)
+# 2. a GSI build step (gsi)
# The setup is run once and the environment is cached,
-# so each build of GSI can reuse the cached dependencies to save time (and compute).
+# so each subsequent build of GSI can reuse the cached dependencies to save time (and compute).
jobs:
setup:
@@ -25,11 +25,11 @@ jobs:
steps:
# Checkout the GSI to get the ci/spack.yaml file
- - name: checkout-gsi
+ - name: checkout
if: steps.cache-env.outputs.cache-hit != 'true'
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
- path: GSI
+ path: gsi
# Cache spack, compiler and dependencies
- name: cache-env
@@ -39,33 +39,34 @@ jobs:
path: |
spack
~/.spack
- key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('GSI/ci/spack.yaml') }}
+ key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('gsi/ci/spack.yaml') }}
# Install dependencies using Spack
- name: install-dependencies-with-spack
if: steps.cache-env.outputs.cache-hit != 'true'
run: |
sudo apt-get install cmake
- git clone -c feature.manyFiles=true https://github.com/NOAA-EMC/spack.git
+ git clone -c feature.manyFiles=true https://github.com/JCSDA/spack.git
source spack/share/spack/setup-env.sh
- spack env create gsi-env GSI/ci/spack.yaml
+ spack env create gsi-env gsi/ci/spack.yaml
spack env activate gsi-env
spack compiler find
+ sudo apt install cmake
spack external find
spack add mpich@3.4.2
spack concretize
spack install -v --fail-fast --dirty
spack clean -a
- build:
+ gsi:
needs: setup
runs-on: ubuntu-latest
steps:
- - name: checkout-gsi
- uses: actions/checkout@v3
+ - name: checkout
+ uses: actions/checkout@v4
with:
- path: GSI
+ path: gsi
- name: cache-env
id: cache-env
@@ -74,13 +75,13 @@ jobs:
path: |
spack
~/.spack
- key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('GSI/ci/spack.yaml') }}
+ key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('gsi/ci/spack.yaml') }}
- - name: build-gsi
+ - name: build
run: |
source spack/share/spack/setup-env.sh
spack env activate gsi-env
- cd GSI
+ cd gsi
mkdir -p build && cd build
cmake -DCMAKE_INSTALL_PREFIX=../install -DGSI_MODE=Regional -DENKF_MODE=GFS -DBUILD_REG_TESTING=OFF ..
make -j2 VERBOSE=1
diff --git a/.github/workflows/intel.yml b/.github/workflows/intel.yml
index d48c00a21e..d21420687a 100644
--- a/.github/workflows/intel.yml
+++ b/.github/workflows/intel.yml
@@ -18,21 +18,30 @@ env:
# The jobs are split into:
# 1. a dependency build step (setup), and
-# 2. a GSI build step (build)
+# 2. a GSI build step (gsi)
# The setup is run once and the environment is cached,
-# so each build of GSI can reuse the cached dependencies to save time (and compute).
+# so each subsequent build of GSI can reuse the cached dependencies to save time (and compute).
jobs:
setup:
runs-on: ubuntu-latest
steps:
+ # Free up disk space
+ - name: free-disk-spack
+ run: |
+ df -h
+ sudo swapoff -a
+ sudo rm -f /swapfile
+ sudo apt clean
+ docker rmi $(docker image ls -aq)
+
# Checkout the GSI to get the ci/spack.yaml file
- - name: checkout-gsi
+ - name: checkout
if: steps.cache-env.outputs.cache-hit != 'true'
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
- path: GSI
+ path: gsi
# Cache spack, compiler and dependencies
- name: cache-env
@@ -43,16 +52,15 @@ jobs:
spack
~/.spack
/opt/intel
- key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('GSI/ci/spack.yaml') }}
+ key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('gsi/ci/spack.yaml') }}
- name: install-intel-compilers
- if: steps.cache-env.outputs.cache-hit != 'true'
run: |
wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB
sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB
echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
sudo apt-get update
- sudo apt-get install intel-oneapi-dev-utilities intel-oneapi-mpi-devel intel-oneapi-openmp intel-oneapi-compiler-fortran intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic
+ sudo apt-get install intel-oneapi-dev-utilities intel-oneapi-mpi-devel intel-oneapi-openmp intel-oneapi-compiler-fortran-2023.2.1 intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2023.2.1
sudo apt-get clean
echo "source /opt/intel/oneapi/setvars.sh" >> ~/.bash_profile
@@ -62,31 +70,32 @@ jobs:
run: |
sudo mv /usr/local/ /usr_local_mv
sudo apt-get install cmake
- git clone -c feature.manyFiles=true https://github.com/NOAA-EMC/spack.git
+ git clone -c feature.manyFiles=true https://github.com/JCSDA/spack.git
source spack/share/spack/setup-env.sh
- spack env create gsi-env GSI/ci/spack.yaml
+ spack env create gsi-env gsi/ci/spack.yaml
spack env activate gsi-env
spack compiler find
+ sudo apt install cmake
spack external find
spack add intel-oneapi-mpi
spack concretize
spack install -v --fail-fast --dirty
spack clean -a
- build:
+ gsi:
needs: setup
runs-on: ubuntu-latest
steps:
- - name: checkout-gsi
- uses: actions/checkout@v3
- with:
- path: GSI
-
- name: install-intel
run: |
echo "source /opt/intel/oneapi/setvars.sh" >> ~/.bash_profile
+ - name: checkout
+ uses: actions/checkout@v4
+ with:
+ path: gsi
+
- name: cache-env
id: cache-env
uses: actions/cache@v3
@@ -95,13 +104,13 @@ jobs:
spack
~/.spack
/opt/intel
- key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('GSI/ci/spack.yaml') }}
+ key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('gsi/ci/spack.yaml') }}
- - name: build-gsi
+ - name: build
run: |
source spack/share/spack/setup-env.sh
spack env activate gsi-env
- cd GSI
+ cd gsi
mkdir -p build && cd build
cmake -DCMAKE_INSTALL_PREFIX=../install -DGSI_MODE=Regional -DENKF_MODE=GFS -DBUILD_REG_TESTING=OFF ..
make -j2 VERBOSE=1
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ac2a6a71c7..176a765262 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,6 +29,7 @@ endif()
option(OPENMP "Enable OpenMP Threading" OFF)
option(ENABLE_MKL "Use MKL for LAPACK implementation (if available)" ON)
option(BUILD_GSDCLOUD "Build GSD Cloud Analysis Library" OFF)
+option(BUILD_MGBF "Build MGBF Library" ON)
option(BUILD_GSI "Build GSI" ON)
option(BUILD_ENKF "Build EnKF" ON)
option(BUILD_REG_TESTING "Build the Regression Testing Suite" OFF)
@@ -37,6 +38,7 @@ option(BUILD_REG_TESTING "Build the Regression Testing Suite" OFF)
message(STATUS "OPENMP ................. ${OPENMP}")
message(STATUS "ENABLE_MKL ............. ${ENABLE_MKL}")
message(STATUS "BUILD_GSDCLOUD ......... ${BUILD_GSDCLOUD}")
+message(STATUS "BUILD_MGBF ............. ${BUILD_MGBF}")
message(STATUS "BUILD_GSI .............. ${BUILD_GSI}")
message(STATUS "BUILD_ENKF ............. ${BUILD_ENKF}")
message(STATUS "BUILD_REG_TESTING ...... ${BUILD_REG_TESTING}")
diff --git a/INSTALL.md b/INSTALL.md
index 8e3187f603..eca09919c3 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -79,6 +79,7 @@ CMake allows for various options that can be specified on the command line via `
| `OPENMP` | Enable OpenMP Threading (`OFF`) |
| `ENABLE_MKL` | Use MKL (`ON`), If not found use LAPACK |
| `BUILD_GSDCLOUD` | Build GSD Cloud Library (`OFF`) |
+| `BUILD_MGBF` | Build MGBF Library (`ON`) |
| `BUILD_GSI` | Build GSI library and executable (`ON`) |
| `BUILD_ENKF` | Build EnKF library and executable (`ON`) |
| `BUILD_REG_TESTING` | Enable Regression Testing (`ON`) |
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000000..0927556b54
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,157 @@
+### GNU LESSER GENERAL PUBLIC LICENSE
+
+Version 3, 29 June 2007
+
+Copyright (C) 2007 Free Software Foundation, Inc.
+
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+This version of the GNU Lesser General Public License incorporates the
+terms and conditions of version 3 of the GNU General Public License,
+supplemented by the additional permissions listed below.
+
+#### 0. Additional Definitions.
+
+As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the
+GNU General Public License.
+
+"The Library" refers to a covered work governed by this License, other
+than an Application or a Combined Work as defined below.
+
+An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+#### 1. Exception to Section 3 of the GNU GPL.
+
+You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+#### 2. Conveying Modified Versions.
+
+If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+- a) under this License, provided that you make a good faith effort
+ to ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+- b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+#### 3. Object Code Incorporating Material from Library Header Files.
+
+The object code form of an Application may incorporate material from a
+header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+- a) Give prominent notice with each copy of the object code that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+- b) Accompany the object code with a copy of the GNU GPL and this
+ license document.
+
+#### 4. Combined Works.
+
+You may convey a Combined Work under terms of your choice that, taken
+together, effectively do not restrict modification of the portions of
+the Library contained in the Combined Work and reverse engineering for
+debugging such modifications, if you also do each of the following:
+
+- a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+- b) Accompany the Combined Work with a copy of the GNU GPL and this
+ license document.
+- c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+- d) Do one of the following:
+ - 0) Convey the Minimal Corresponding Source under the terms of
+ this License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+ - 1) Use a suitable shared library mechanism for linking with
+ the Library. A suitable mechanism is one that (a) uses at run
+ time a copy of the Library already present on the user's
+ computer system, and (b) will operate properly with a modified
+ version of the Library that is interface-compatible with the
+ Linked Version.
+- e) Provide Installation Information, but only if you would
+ otherwise be required to provide such information under section 6
+ of the GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the Application
+ with a modified version of the Linked Version. (If you use option
+ 4d0, the Installation Information must accompany the Minimal
+ Corresponding Source and Corresponding Application Code. If you
+ use option 4d1, you must provide the Installation Information in
+ the manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.)
+
+#### 5. Combined Libraries.
+
+You may place library facilities that are a work based on the Library
+side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+- a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities, conveyed under the terms of this License.
+- b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+#### 6. Revised Versions of the GNU Lesser General Public License.
+
+The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+as you received it specifies that a certain numbered version of the
+GNU Lesser General Public License "or any later version" applies to
+it, you have the option of following the terms and conditions either
+of that published version or of any later version published by the
+Free Software Foundation. If the Library as you received it does not
+specify a version number of the GNU Lesser General Public License, you
+may choose any version of the GNU Lesser General Public License ever
+published by the Free Software Foundation.
+
+If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/ci/spack.yaml b/ci/spack.yaml
index eeb9f95512..647904108e 100644
--- a/ci/spack.yaml
+++ b/ci/spack.yaml
@@ -6,20 +6,20 @@ spack:
- intel
- gcc@10:10
specs:
- - netcdf-c@4.7.4
- - netcdf-fortran@4.5.3
+ - netcdf-c@4.9.2
+ - netcdf-fortran@4.6.1
- bufr@11.7.0
- bacio@2.4.1
- - w3emc@2.9.2
- - sp@2.3.3
- - ip@3.3.3
+ - w3emc@2.10.0
+ - sp@2.5.0
+ - ip@4.3.0
- sigio@2.3.2
- sfcio@1.4.1
- - nemsio@2.5.2
+ - nemsio@2.5.4
- wrf-io@1.2.0
- ncio@1.1.2
- - crtm@2.3.0
- - gsi-ncdiag@1.0.0
+ - crtm@2.4.0.1
+ - gsi-ncdiag@1.1.2
view: true
concretizer:
unify: true
diff --git a/fix b/fix
index 0be26971f8..15ffa60307 160000
--- a/fix
+++ b/fix
@@ -1 +1 @@
-Subproject commit 0be26971f834fe9b1d5b118e1e0ffed53facf671
+Subproject commit 15ffa60307bbc19746d8caeb41782de0b7604be6
diff --git a/modulefiles/gsi_cheyenne.gnu.lua b/modulefiles/gsi_cheyenne.gnu.lua
deleted file mode 100644
index 494ec6fb18..0000000000
--- a/modulefiles/gsi_cheyenne.gnu.lua
+++ /dev/null
@@ -1,32 +0,0 @@
-help([[
-]])
-
-load("cmake/3.22.0")
-load("python/3.7.9")
-load("ncarenv/1.3")
-load("gnu/10.1.0")
-load("mpt/2.22")
-load("ncarcompilers/0.5.0")
-unload("netcdf")
-
-prepend_path("MODULEPATH", "/glade/work/epicufsrt/GMTB/tools/gnu/10.1.0/hpc-stack-v1.2.0/modulefiles/stack")
-
-load("hpc/1.2.0")
-load("hpc-gnu/10.1.0")
-load("hpc-mpt/2.22")
-
--- Preload w3nco to work around nemsio "find_dependency(w3nco)" hpc-stack bug
-load("w3nco/2.4.1")
-
-load("gsi_common")
-
-local prod_util_ver=os.getenv("prod_util_ver") or "1.2.2"
-load(pathJoin("prod_util", prod_util_ver))
-
-pushenv("MKLROOT", "/glade/u/apps/opt/intel/2022.1/mkl/latest")
-
-pushenv("CC", "mpicc")
-pushenv("FC", "mpif90")
-pushenv("CXX", "mpicxx")
-
-whatis("Description: GSI environment on Cheyenne with GNU Compilers")
diff --git a/modulefiles/gsi_cheyenne.intel.lua b/modulefiles/gsi_cheyenne.intel.lua
deleted file mode 100644
index 72bf458516..0000000000
--- a/modulefiles/gsi_cheyenne.intel.lua
+++ /dev/null
@@ -1,26 +0,0 @@
-help([[
-]])
-
-load("cmake/3.22.0")
-load("python/3.7.9")
-load("ncarenv/1.3")
-load("intel/2022.1")
-load("mpt/2.25")
-load("ncarcompilers/0.5.0")
-
-prepend_path("MODULEPATH", "/glade/work/epicufsrt/GMTB/tools/intel/2022.1/hpc-stack-v1.2.0_6eb6/modulefiles/stack")
-
-load("hpc/1.2.0")
-load("hpc-intel/2022.1")
-load("hpc-mpt/2.25")
-load("mkl/2022.1")
-
-load("gsi_common")
-
-local prod_util_ver=os.getenv("prod_util_ver") or "1.2.2"
-load(pathJoin("prod_util", prod_util_ver))
-
-pushenv("CFLAGS", "-xHOST")
-pushenv("FFLAGS", "-xHOST")
-
-whatis("Description: GSI environment on Cheyenne with Intel Compilers")
diff --git a/modulefiles/gsi_common.lua b/modulefiles/gsi_common.lua
index 6844372324..cb49a43878 100644
--- a/modulefiles/gsi_common.lua
+++ b/modulefiles/gsi_common.lua
@@ -2,22 +2,24 @@ help([[
Load common modules to build GSI on all machines
]])
-local netcdf_ver=os.getenv("netcdf_ver") or "4.7.4"
+local netcdf_c_ver=os.getenv("netcdf_c_ver") or "4.9.2"
+local netcdf_fortran_ver=os.getenv("netcdf_fortran_ver") or "4.6.1"
local bufr_ver=os.getenv("bufr_ver") or "11.7.0"
local bacio_ver=os.getenv("bacio_ver") or "2.4.1"
-local w3emc_ver=os.getenv("w3emc_ver") or "2.9.1"
-local sp_ver=os.getenv("sp_ver") or "2.3.3"
-local ip_ver=os.getenv("ip_ver") or "3.3.3"
+local w3emc_ver=os.getenv("w3emc_ver") or "2.10.0"
+local sp_ver=os.getenv("sp_ver") or "2.5.0"
+local ip_ver=os.getenv("ip_ver") or "4.3.0"
local sigio_ver=os.getenv("sigio_ver") or "2.3.2"
local sfcio_ver=os.getenv("sfcio_ver") or "1.4.1"
-local nemsio_ver=os.getenv("nemsio_ver") or "2.5.2"
+local nemsio_ver=os.getenv("nemsio_ver") or "2.5.4"
local wrf_io_ver=os.getenv("wrf_io_ver") or "1.2.0"
local ncio_ver=os.getenv("ncio_ver") or "1.1.2"
-local crtm_ver=os.getenv("crtm_ver") or "2.3.0"
-local ncdiag_ver=os.getenv("ncdiag_ver") or "1.0.0"
+local crtm_ver=os.getenv("crtm_ver") or "2.4.0.1"
+local ncdiag_ver=os.getenv("ncdiag_ver") or "1.1.2"
-load(pathJoin("netcdf", netcdf_ver))
+load(pathJoin("netcdf-c", netcdf_c_ver))
+load(pathJoin("netcdf-fortran", netcdf_fortran_ver))
load(pathJoin("bufr", bufr_ver))
load(pathJoin("bacio", bacio_ver))
@@ -27,8 +29,7 @@ load(pathJoin("ip", ip_ver))
load(pathJoin("sigio", sigio_ver))
load(pathJoin("sfcio", sfcio_ver))
load(pathJoin("nemsio", nemsio_ver))
-load(pathJoin("wrf_io", wrf_io_ver))
+load(pathJoin("wrf-io", wrf_io_ver))
load(pathJoin("ncio", ncio_ver))
load(pathJoin("crtm", crtm_ver))
-load(pathJoin("ncdiag",ncdiag_ver))
-
+load(pathJoin("gsi-ncdiag",ncdiag_ver))
diff --git a/modulefiles/gsi_discover b/modulefiles/gsi_discover.intel
similarity index 100%
rename from modulefiles/gsi_discover
rename to modulefiles/gsi_discover.intel
diff --git a/modulefiles/gsi_gaea b/modulefiles/gsi_gaea
deleted file mode 100644
index 91089895a1..0000000000
--- a/modulefiles/gsi_gaea
+++ /dev/null
@@ -1,65 +0,0 @@
-#%Module1.0
-######################################################################
-## NOAA-EMC/GSI
-##_____________________________________________________
-proc ModulesHelp { } {
-puts stderr "Set environment variables for NOAA-EMC/GSI"
-puts stderr "This module initializes the environment "
-puts stderr "for the Intel Compiler Suite $version\n"
-}
-module-whatis " NOAA-EMC/GSI whatis description"
-
-set COMPILER intel
-
-setenv FFLAGS_COM "-fp-model strict"
-setenv LDFLAGS_COM " "
-
-#set WRF_SHARED_VER v1.1.0
-#set WRF_SHARED_ROOT /gpfs/hps/nco/ops/nwprod/wrf_shared
-#set WRF_SHARED_ROOT /lustre/f1/pdata/ncep_shared/NCEPLIBS/lib/EXTERNAL/wrf_shared
-#setenv WRF_SHARED_PATH ${WRF_SHARED_ROOT}.${WRF_SHARED_VER}
-
-setenv NCEPLIBS /lustre/f1/pdata/ncep_shared/NCEPLIBS/lib
-
-# Loading ncep environment
-##module load ncep/1.0
-module use /opt/cray/pe/craype/2.5.5/modulefiles
-
-# Loading Intel Compiler Suite
-module load PrgEnv-intel
-
-# Loading pe environment
-module load cray-mpich
-module load cray-libsci
-module unload craype-broadwell
-module load craype-haswell
-
-module use /sw/gaea/modulefiles
-module load cmake
-
-# Loading nceplibs modules
-module use /lustre/f1/pdata/ncep_shared/NCEPLIBS/lib/modulefiles
-#module load HDF5-serial-intel-haswell/1.8.9
-#module load NetCDF-intel-haswell/4.2
-module load cray-hdf5
-module load cray-netcdf
-
-#module use /gpfs/hps/nco/ops/nwprod/lib/modulefiles
-module load bufr-intel-sandybridge/11.0.1
-module load nemsio-intel-sandybridge/2.2.2
-module load sfcio-intel-sandybridge/1.0.0
-module load sigio-intel-sandybridge/2.0.1
-module load sp-intel-sandybridge/2.0.2
-module load w3nco-intel-sandybridge/2.0.6
-module load w3emc-intel-sandybridge/2.2.0
-module load crtm-intel/2.2.4
-#setenv CRTM_INC /lustre/f1/pdata/ncep_shared/NCEPLIBS/lib/crtm/v2.2.4/intel/include/crtm_v2.2.4
-#setenv CRTM_LIB /lustre/f1/pdata/ncep_shared/NCEPLIBS/lib/crtm/v2.2.4/intel/libcrtm_v2.2.4.a
-module load bacio-intel-sandybridge/2.0.2
-setenv CRAYOS_VERSION $::env(CRAYPE_VERSION)
-#setenv CRAYOS_VERSION ${CRAYPE_VERSION}
-
-# Compiler flags specific to this platform
-setenv CFLAGS "-xCORE-AVX2"
-setenv FFLAGS "-xCORE-AVX2"
-
diff --git a/modulefiles/gsi_gaea.intel.lua b/modulefiles/gsi_gaea.intel.lua
new file mode 100644
index 0000000000..799822caa8
--- /dev/null
+++ b/modulefiles/gsi_gaea.intel.lua
@@ -0,0 +1,32 @@
+help([[
+]])
+
+prepend_path("MODULEPATH", "/ncrc/proj/epic/spack-stack/spack-stack-1.6.0/envs/gsi-addon-dev/install/modulefiles/Core")
+
+local stack_python_ver=os.getenv("stack_python_ver") or "3.11.6"
+local stack_intel_ver=os.getenv("stack_intel_ver") or "2023.1.0"
+local stack_cray_mpich_ver=os.getenv("stack_cray_mpich_ver") or "8.1.25"
+local cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+local prod_util_ver=os.getenv("prod_util_ver") or "2.1.1"
+
+load(pathJoin("stack-intel", stack_intel_ver))
+load(pathJoin("stack-cray-mpich", stack_cray_mpich_ver))
+load(pathJoin("stack-python", stack_python_ver))
+load(pathJoin("cmake", cmake_ver))
+
+load("gsi_common")
+load(pathJoin("prod_util", prod_util_ver))
+
+local MKLROOT="/opt/intel/oneapi/mkl/2022.0.2/"
+prepend_path("LD_LIBRARY_PATH",pathJoin(MKLROOT,"lib/intel64"))
+pushenv("MKLROOT", MKLROOT)
+
+pushenv("GSI_BINARY_SOURCE_DIR", "/gpfs/f5/ufs-ard/world-shared/GSI_data/fix/gsi/20240208")
+
+setenv("CC","cc")
+setenv("FC","ftn")
+setenv("CXX","CC")
+pushenv("CRAYPE_LINK_TYPE","dynamic")
+
+unload("cray-libsci")
+whatis("Description: GSI environment on Gaea with Intel Compilers")
diff --git a/modulefiles/gsi_hera.gnu.lua b/modulefiles/gsi_hera.gnu.lua
index 3ed9fbddb0..eab352553f 100644
--- a/modulefiles/gsi_hera.gnu.lua
+++ b/modulefiles/gsi_hera.gnu.lua
@@ -1,25 +1,27 @@
help([[
]])
-prepend_path("MODULEPATH", "/scratch2/NCEPDEV/nwprod/hpc-stack/libs/hpc-stack/modulefiles/stack")
-
-local hpc_ver=os.getenv("hpc_ver") or "1.1.0"
-local hpc_gnu_ver=os.getenv("hpc_gnu_ver") or "9.2.0"
-local hpc_mpich_ver=os.getenv("hpc_mpich_ver") or "3.3.2"
-local cmake_ver=os.getenv("cmake_ver") or "3.20.1"
-local prod_util_ver=os.getenv("prod_util_ver") or "1.2.2"
-
-load(pathJoin("hpc", hpc_ver))
-load(pathJoin("hpc-gnu", hpc_gnu_ver))
-load(pathJoin("hpc-mpich", hpc_mpich_ver))
+prepend_path("MODULEPATH", "/scratch1/NCEPDEV/nems/role.epic/spack-stack/spack-stack-1.6.0/envs/gsi-addon-dev/install/modulefiles/Core")
+--Needed for openmpi build
+prepend_path("MODULEPATH", "/scratch1/NCEPDEV/jcsda/jedipara/spack-stack/modulefiles")
+
+local python_ver=os.getenv("python_ver") or "3.11.6"
+local stack_gnu_ver=os.getenv("stack_gnu_ver") or "9.2.0"
+local stack_openmpi_ver=os.getenv("stack_openmpi_ver") or "4.1.5"
+local cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+local prod_util_ver=os.getenv("prod_util_ver") or "2.1.1"
+local openblas_ver=os.getenv("openblas_ver") or "0.3.24"
+
+load(pathJoin("stack-gcc", stack_gnu_ver))
+load(pathJoin("stack-openmpi", stack_openmpi_ver))
+load(pathJoin("python", python_ver))
load(pathJoin("cmake", cmake_ver))
load("gsi_common")
load(pathJoin("prod_util", prod_util_ver))
+load(pathJoin("openblas", openblas_ver))
-pushenv("MKLROOT", "/apps/oneapi/mkl/2022.0.2")
-
-pushenv("GSI_BINARY_SOURCE_DIR", "/scratch1/NCEPDEV/global/glopara/fix/gsi/20221128")
+pushenv("GSI_BINARY_SOURCE_DIR", "/scratch1/NCEPDEV/global/glopara/fix/gsi/20240208")
whatis("Description: GSI environment on Hera with GNU Compilers")
diff --git a/modulefiles/gsi_hera.intel.lua b/modulefiles/gsi_hera.intel.lua
index 1efb6f4405..d21b9195c3 100644
--- a/modulefiles/gsi_hera.intel.lua
+++ b/modulefiles/gsi_hera.intel.lua
@@ -1,31 +1,25 @@
help([[
]])
-prepend_path("MODULEPATH", "/scratch2/NCEPDEV/nwprod/hpc-stack/libs/hpc-stack/modulefiles/stack")
+prepend_path("MODULEPATH", "/scratch1/NCEPDEV/nems/role.epic/spack-stack/spack-stack-1.6.0/envs/gsi-addon-dev-rocky8/install/modulefiles/Core")
-local hpc_ver=os.getenv("hpc_ver") or "1.1.0"
-local hpc_intel_ver=os.getenv("hpc_intel_ver") or "18.0.5.274"
-local hpc_impi_ver=os.getenv("hpc_impi_ver") or "2018.0.4"
-local cmake_ver=os.getenv("cmake_ver") or "3.20.1"
-local anaconda_ver=os.getenv("anaconda_ver") or "2.3.0"
-local prod_util_ver=os.getenv("prod_util_ver") or "1.2.2"
+local python_ver=os.getenv("python_ver") or "3.11.6"
+local stack_intel_ver=os.getenv("stack_intel_ver") or "2021.5.0"
+local stack_impi_ver=os.getenv("stack_impi_ver") or "2021.5.1"
+local cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+local prod_util_ver=os.getenv("prod_util_ver") or "2.1.1"
-load(pathJoin("hpc", hpc_ver))
-load(pathJoin("hpc-intel", hpc_intel_ver))
-load(pathJoin("hpc-impi", hpc_impi_ver))
+load(pathJoin("stack-intel", stack_intel_ver))
+load(pathJoin("stack-intel-oneapi-mpi", stack_impi_ver))
+load(pathJoin("python", python_ver))
load(pathJoin("cmake", cmake_ver))
-prepend_path("MODULEPATH", "/contrib/anaconda/modulefiles")
-
-load(pathJoin("anaconda", anaconda_ver))
-
load("gsi_common")
-
load(pathJoin("prod_util", prod_util_ver))
pushenv("CFLAGS", "-xHOST")
pushenv("FFLAGS", "-xHOST")
-pushenv("GSI_BINARY_SOURCE_DIR", "/scratch1/NCEPDEV/global/glopara/fix/gsi/20221128")
+pushenv("GSI_BINARY_SOURCE_DIR", "/scratch1/NCEPDEV/global/glopara/fix/gsi/20240208")
whatis("Description: GSI environment on Hera with Intel Compilers")
diff --git a/modulefiles/gsi_hercules.intel.lua b/modulefiles/gsi_hercules.intel.lua
new file mode 100644
index 0000000000..597cc87291
--- /dev/null
+++ b/modulefiles/gsi_hercules.intel.lua
@@ -0,0 +1,36 @@
+help([[
+]])
+
+prepend_path("MODULEPATH", "/work/noaa/epic/role-epic/spack-stack/hercules/spack-stack-1.6.0/envs/gsi-addon-env/install/modulefiles/Core")
+
+local stack_python_ver=os.getenv("stack_python_ver") or "3.11.6"
+local stack_intel_ver=os.getenv("stack_intel_ver") or "2021.9.0"
+local stack_impi_ver=os.getenv("stack_impi_ver") or "2021.9.0"
+local cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+local prod_util_ver=os.getenv("prod_util_ver") or "2.1.1"
+
+load(pathJoin("stack-intel", stack_intel_ver))
+load(pathJoin("stack-intel-oneapi-mpi", stack_impi_ver))
+load(pathJoin("python", stack_python_ver))
+load(pathJoin("cmake", cmake_ver))
+
+load("gsi_common")
+setenv("crtm_ROOT","/work/noaa/da/eliu/HERCULES/CRTM/crtm_v2.4.1-jedi.1/build")
+setenv("crtm_VERSION","2.4.1-jedi.1")
+setenv("CRTM_INC","/work/noaa/da/eliu/HERCULES/CRTM/crtm_v2.4.1-jedi.1/build/module")
+setenv("CRTM_LIB","/work/noaa/da/eliu/HERCULES/CRTM/crtm_v2.4.1-jedi.1/build/lib/libcrtm_static.a")
+setenv("CRTM_FIX","/work/noaa/da/eliu/HERCULES/CRTM-fix/crtm_v2.4.1-jedi.1-fix_gdasapp")
+whatis("Name: crtm")
+whatis("Version: 2.4.1-jedi.1")
+whatis("Category: library")
+whatis("Description: crtm library")
+
+load(pathJoin("prod_util", prod_util_ver))
+load("intel-oneapi-mkl/2022.2.1")
+
+pushenv("CFLAGS", "-xHOST")
+pushenv("FFLAGS", "-xHOST")
+
+pushenv("GSI_BINARY_SOURCE_DIR", "/work/noaa/global/glopara/fix/gsi/20240208")
+
+whatis("Description: GSI environment on Hercules with Intel Compilers")
diff --git a/modulefiles/gsi_jet.intel.lua b/modulefiles/gsi_jet.intel.lua
new file mode 100644
index 0000000000..48189ba241
--- /dev/null
+++ b/modulefiles/gsi_jet.intel.lua
@@ -0,0 +1,25 @@
+help([[
+]])
+
+prepend_path("MODULEPATH", "/mnt/lfs4/HFIP/hfv3gfs/role.epic/spack-stack/spack-stack-1.6.0/envs/gsi-addon-dev-rocky8/install/modulefiles/Core")
+
+local python_ver=os.getenv("python_ver") or "3.11.6"
+local stack_intel_ver=os.getenv("stack_intel_ver") or "2021.5.0"
+local stack_impi_ver=os.getenv("stack_impi_ver") or "2021.5.1"
+local cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+local prod_util_ver=os.getenv("prod_util_ver") or "2.1.1"
+
+load(pathJoin("stack-intel", stack_intel_ver))
+load(pathJoin("stack-intel-oneapi-mpi", stack_impi_ver))
+load(pathJoin("python", python_ver))
+load(pathJoin("cmake", cmake_ver))
+
+load("gsi_common")
+load(pathJoin("prod_util", prod_util_ver))
+
+pushenv("CFLAGS", "-axSSE4.2,AVX,CORE-AVX2")
+pushenv("FFLAGS", "-axSSE4.2,AVX,CORE-AVX2")
+
+pushenv("GSI_BINARY_SOURCE_DIR", "/mnt/lfs4/HFIP/hfv3gfs/glopara/git/fv3gfs/fix/gsi/20240208")
+
+whatis("Description: GSI environment on Jet with Intel Compilers")
diff --git a/modulefiles/gsi_jet.lua b/modulefiles/gsi_jet.lua
deleted file mode 100644
index ddb255bc1f..0000000000
--- a/modulefiles/gsi_jet.lua
+++ /dev/null
@@ -1,26 +0,0 @@
-help([[
-]])
-
-load("cmake/3.20.1")
-
-prepend_path("MODULEPATH", "/contrib/anaconda/modulefiles")
-
-load("anaconda/5.3.1")
-
-prepend_path("MODULEPATH", "/lfs4/HFIP/hfv3gfs/nwprod/hpc-stack/libs/modulefiles/stack")
-
-load("hpc/1.1.0")
-load("hpc-intel/18.0.5.274")
-load("hpc-impi/2018.4.274")
-
-load("gsi_common")
-
-local prod_util_ver=os.getenv("prod_util_ver") or "1.2.2"
-load(pathJoin("prod_util", prod_util_ver))
-
-pushenv("CFLAGS", "-axSSE4.2,AVX,CORE-AVX2")
-pushenv("FFLAGS", "-axSSE4.2,AVX,CORE-AVX2")
-
-pushenv("GSI_BINARY_SOURCE_DIR", "/lfs4/HFIP/hfv3gfs/glopara/git/fv3gfs/fix/gsi/20221128")
-
-whatis("Description: GSI environment on Jet with Intel Compilers")
diff --git a/modulefiles/gsi_noaacloud.intel.lua b/modulefiles/gsi_noaacloud.intel.lua
new file mode 100644
index 0000000000..e2e019628e
--- /dev/null
+++ b/modulefiles/gsi_noaacloud.intel.lua
@@ -0,0 +1,25 @@
+help([[
+]])
+
+prepend_path("MODULEPATH", "/contrib/spack-stack/spack-stack-1.6.0/envs/gsi-addon-env/install/modulefiles/Core")
+
+local python_ver=os.getenv("python_ver") or "3.10.13"
+local stack_intel_ver=os.getenv("stack_intel_ver") or "2021.3.0"
+local stack_impi_ver=os.getenv("stack_impi_ver") or "2021.3.0"
+local cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+local prod_util_ver=os.getenv("prod_util_ver") or "2.1.1"
+
+load(pathJoin("stack-intel", stack_intel_ver))
+load(pathJoin("stack-intel-oneapi-mpi", stack_impi_ver))
+load(pathJoin("python", python_ver))
+load(pathJoin("cmake", cmake_ver))
+
+load("gsi_common")
+load(pathJoin("prod_util", prod_util_ver))
+
+pushenv("CFLAGS", "-xHOST")
+pushenv("FFLAGS", "-xHOST")
+
+pushenv("GSI_BINARY_SOURCE_DIR", "/contrib/Wei.Huang/data/hack-orion/fix/gsi/20240208")
+
+whatis("Description: GSI environment on NOAA Cloud with Intel Compilers")
diff --git a/modulefiles/gsi_orion.intel.lua b/modulefiles/gsi_orion.intel.lua
new file mode 100644
index 0000000000..ede89f5b77
--- /dev/null
+++ b/modulefiles/gsi_orion.intel.lua
@@ -0,0 +1,36 @@
+help([[
+]])
+
+prepend_path("MODULEPATH", "/work/noaa/epic/role-epic/spack-stack/orion/spack-stack-1.6.0/envs/gsi-addon-env-rocky9/install/modulefiles/Core")
+
+local stack_python_ver=os.getenv("stack_python_ver") or "3.11.6"
+local stack_intel_ver=os.getenv("stack_intel_ver") or "2021.9.0"
+local stack_impi_ver=os.getenv("stack_impi_ver") or "2021.9.0"
+local cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+local prod_util_ver=os.getenv("prod_util_ver") or "2.1.1"
+
+load(pathJoin("stack-intel", stack_intel_ver))
+load(pathJoin("stack-intel-oneapi-mpi", stack_impi_ver))
+load(pathJoin("python", stack_python_ver))
+load(pathJoin("cmake", cmake_ver))
+
+load("gsi_common")
+setenv("crtm_ROOT","/work/noaa/da/eliu/ORION/CRTM/crtm_v2.4.1-jedi.1/build")
+setenv("crtm_VERSION","2.4.1-jedi.1")
+setenv("CRTM_INC","/work/noaa/da/eliu/ORION/CRTM/crtm_v2.4.1-jedi.1/build/module")
+setenv("CRTM_LIB","/work/noaa/da/eliu/ORION/CRTM/crtm_v2.4.1-jedi.1/build/lib/libcrtm_static.a")
+setenv("CRTM_FIX","/work/noaa/da/eliu/ORION/CRTM-fix/crtm_v2.4.1-jedi.1-fix_gdasapp")
+whatis("Name: crtm")
+whatis("Version: 2.4.1-jedi.1")
+whatis("Category: library")
+whatis("Description: crtm library")
+
+load(pathJoin("prod_util", prod_util_ver))
+load("intel-oneapi-mkl/2022.2.1")
+
+pushenv("CFLAGS", "-xHOST")
+pushenv("FFLAGS", "-xHOST")
+
+pushenv("GSI_BINARY_SOURCE_DIR", "/work/noaa/global/glopara/fix/gsi/20240208")
+
+whatis("Description: GSI environment on Orion with Intel Compilers")
diff --git a/modulefiles/gsi_orion.lua b/modulefiles/gsi_orion.lua
deleted file mode 100644
index b69467f7ce..0000000000
--- a/modulefiles/gsi_orion.lua
+++ /dev/null
@@ -1,28 +0,0 @@
-help([[
-]])
-
-prepend_path("MODULEPATH", "/apps/contrib/NCEP/libs/hpc-stack/modulefiles/stack")
-
-local hpc_ver=os.getenv("hpc_ver") or "1.1.0"
-local hpc_intel_ver=os.getenv("hpc_intel_ver") or "2018.4"
-local hpc_impi_ver=os.getenv("hpc_impi_ver") or "2018.4"
-local cmake_ver=os.getenv("cmake_ver") or "3.22.1"
-local python_ver=os.getenv("python_ver") or "3.7.5"
-local prod_util_ver=os.getenv("prod_util_ver") or "1.2.2"
-
-load(pathJoin("hpc", hpc_ver))
-load(pathJoin("hpc-intel", hpc_intel_ver))
-load(pathJoin("hpc-impi", hpc_impi_ver))
-load(pathJoin("cmake", cmake_ver))
-load(pathJoin("python", python_ver))
-
-load("gsi_common")
-
-load(pathJoin("prod_util", prod_util_ver))
-
-pushenv("CFLAGS", "-xHOST")
-pushenv("FFLAGS", "-xHOST")
-
-pushenv("GSI_BINARY_SOURCE_DIR", "/work/noaa/global/glopara/fix/gsi/20221128")
-
-whatis("Description: GSI environment on Orion with Intel Compilers")
diff --git a/modulefiles/gsi_s4.intel.lua b/modulefiles/gsi_s4.intel.lua
new file mode 100644
index 0000000000..04945eef3e
--- /dev/null
+++ b/modulefiles/gsi_s4.intel.lua
@@ -0,0 +1,25 @@
+help([[
+]])
+
+prepend_path("MODULEPATH", "/data/prod/jedi/spack-stack/spack-stack-1.6.0/envs/gsi-addon-env/install/modulefiles/Core")
+
+local python_ver=os.getenv("python_ver") or "3.11.6"
+local stack_intel_ver=os.getenv("stack_intel_ver") or "2021.5.0"
+local stack_impi_ver=os.getenv("stack_impi_ver") or "2021.5.0"
+local cmake_ver=os.getenv("cmake_ver") or "3.23.1"
+local prod_util_ver=os.getenv("prod_util_ver") or "2.1.1"
+
+load(pathJoin("stack-intel", stack_intel_ver))
+load(pathJoin("stack-intel-oneapi-mpi", stack_impi_ver))
+load(pathJoin("python", python_ver))
+load(pathJoin("cmake", cmake_ver))
+
+load("gsi_common")
+load(pathJoin("prod_util", prod_util_ver))
+
+pushenv("CFLAGS", "-march=ivybridge")
+pushenv("FFLAGS", "-march=ivybridge")
+
+pushenv("GSI_BINARY_SOURCE_DIR", "/data/prod/glopara/fix/gsi/20240208")
+
+whatis("Description: GSI environment on S4 with Intel Compilers")
diff --git a/modulefiles/gsi_s4.lua b/modulefiles/gsi_s4.lua
deleted file mode 100644
index f393ce516a..0000000000
--- a/modulefiles/gsi_s4.lua
+++ /dev/null
@@ -1,28 +0,0 @@
-help([[
-]])
-
-local hpc_ver=os.getenv("hpc_ver") or "1.1.0"
-local hpc_intel_ver=os.getenv("hpc_intel_ver") or "18.0.4"
-local hpc_impi_ver=os.getenv("hpc_impi_ver") or "18.0.4"
-local miniconda_ver=os.getenv("miniconda_ver") or "3.8-s4"
-local prod_util_ver=os.getenv("prod_util_ver") or "1.2.2"
-
-prepend_path("MODULEPATH", "/data/prod/hpc-stack/modulefiles/stack")
-
-load("license_intel/S4")
-load(pathJoin("hpc", hpc_ver))
-load(pathJoin("hpc-intel", hpc_intel_ver))
-load(pathJoin("hpc-impi", hpc_impi_ver))
-
-load(pathJoin("miniconda", miniconda_ver))
-
-load("gsi_common")
-
-load(pathJoin("prod_util", prod_util_ver))
-
-pushenv("CFLAGS", "-march=ivybridge")
-pushenv("FFLAGS", "-march=ivybridge")
-
-pushenv("GSI_BINARY_SOURCE_DIR", "/data/prod/glopara/fix/gsi/20221128")
-
-whatis("Description: GSI environment on S4 with Intel Compilers")
diff --git a/modulefiles/gsi_wcoss2.intel.lua b/modulefiles/gsi_wcoss2.intel.lua
new file mode 100644
index 0000000000..c3bfd1156c
--- /dev/null
+++ b/modulefiles/gsi_wcoss2.intel.lua
@@ -0,0 +1,51 @@
+help([[
+]])
+
+local PrgEnv_intel_ver=os.getenv("PrgEnv_intel_ver") or "8.1.0"
+local intel_ver=os.getenv("intel_ver") or "19.1.3.304"
+local craype_ver=os.getenv("craype_ver") or "2.7.8"
+local cray_mpich_ver=os.getenv("cray_mpich_ver") or "8.1.7"
+local cmake_ver= os.getenv("cmake_ver") or "3.20.2"
+local python_ver=os.getenv("python_ver") or "3.8.6"
+local prod_util_ver=os.getenv("prod_util_ver") or "2.0.10"
+
+local netcdf_ver=os.getenv("netcdf_ver") or "4.7.4"
+local bufr_ver=os.getenv("bufr_ver") or "11.7.0"
+local bacio_ver=os.getenv("bacio_ver") or "2.4.1"
+local w3emc_ver=os.getenv("w3emc_ver") or "2.9.2"
+local sp_ver=os.getenv("sp_ver") or "2.3.3"
+local ip_ver=os.getenv("ip_ver") or "3.3.3"
+local sigio_ver=os.getenv("sigio_ver") or "2.3.2"
+local sfcio_ver=os.getenv("sfcio_ver") or "1.4.1"
+local nemsio_ver=os.getenv("nemsio_ver") or "2.5.4"
+local wrf_io_ver=os.getenv("wrf_io_ver") or "1.2.0"
+local ncio_ver=os.getenv("ncio_ver") or "1.1.2"
+local crtm_ver=os.getenv("crtm_ver") or "2.4.0.1"
+local ncdiag_ver=os.getenv("ncdiag_ver") or "1.1.1"
+
+load(pathJoin("PrgEnv-intel", PrgEnv_intel_ver))
+load(pathJoin("intel", intel_ver))
+load(pathJoin("craype", craype_ver))
+load(pathJoin("cray-mpich", cray_mpich_ver))
+load(pathJoin("cmake", cmake_ver))
+load(pathJoin("python", python_ver))
+
+load(pathJoin("prod_util", prod_util_ver))
+
+load(pathJoin("netcdf", netcdf_ver))
+load(pathJoin("bufr", bufr_ver))
+load(pathJoin("bacio", bacio_ver))
+load(pathJoin("w3emc", w3emc_ver))
+load(pathJoin("sp", sp_ver))
+load(pathJoin("ip", ip_ver))
+load(pathJoin("sigio", sigio_ver))
+load(pathJoin("sfcio", sfcio_ver))
+load(pathJoin("nemsio", nemsio_ver))
+load(pathJoin("wrf_io", wrf_io_ver))
+load(pathJoin("ncio", ncio_ver))
+load(pathJoin("crtm", crtm_ver))
+load(pathJoin("ncdiag",ncdiag_ver))
+
+pushenv("GSI_BINARY_SOURCE_DIR", "/lfs/h2/emc/global/noscrub/emc.global/FIX/fix/gsi/20240208")
+
+whatis("Description: GSI environment on WCOSS2")
diff --git a/modulefiles/gsi_wcoss2.lua b/modulefiles/gsi_wcoss2.lua
deleted file mode 100644
index 84ffce874a..0000000000
--- a/modulefiles/gsi_wcoss2.lua
+++ /dev/null
@@ -1,34 +0,0 @@
-help([[
-]])
-
-local PrgEnv_intel_ver=os.getenv("PrgEnv_intel_ver") or "8.1.0"
-local intel_ver=os.getenv("intel_ver") or "19.1.3.304"
-local craype_ver=os.getenv("craype_ver") or "2.7.8"
-local cray_mpich_ver=os.getenv("cray_mpich_ver") or "8.1.7"
-local cmake_ver= os.getenv("cmake_ver") or "3.20.2"
-local python_ver=os.getenv("python_ver") or "3.8.6"
-local prod_util_ver=os.getenv("prod_util_ver") or "2.0.10"
-
-load(pathJoin("PrgEnv-intel", PrgEnv_intel_ver))
-load(pathJoin("intel", intel_ver))
-load(pathJoin("craype", craype_ver))
-load(pathJoin("cray-mpich", cray_mpich_ver))
-load(pathJoin("cmake", cmake_ver))
-load(pathJoin("python", python_ver))
-
-load(pathJoin("prod_util", prod_util_ver))
-
-load("gsi_common")
-unload("ncio")
-unload("ncdiag")
-
-pushenv("HPC_OPT", "/apps/ops/para/libs")
-prepend_path("MODULEPATH", "/apps/ops/para/libs/modulefiles/compiler/intel/19.1.3.304")
-prepend_path("MODULEPATH", "/apps/ops/para/libs/modulefiles/mpi/intel/19.1.3.304/cray-mpich/8.1.7")
-
-load("ncio/1.1.2")
-load("ncdiag/1.0.0")
-
-pushenv("GSI_BINARY_SOURCE_DIR", "/lfs/h2/emc/global/noscrub/emc.global/FIX/fix/gsi/20221128")
-
-whatis("Description: GSI environment on WCOSS2")
diff --git a/regression/CMakeLists.txt b/regression/CMakeLists.txt
index cfbce04b40..e36cca605b 100644
--- a/regression/CMakeLists.txt
+++ b/regression/CMakeLists.txt
@@ -38,15 +38,22 @@ endif()
# GSI regression test names
list(APPEND GSI_REG_TEST_NAMES
- global_3dvar global_4dvar global_4denvar
- hwrf_nmm_d2 hwrf_nmm_d3 rtma
- rrfs_3denvar_glbens netcdf_fv3_regional
+ global_4denvar
+ rtma
+ rrfs_3denvar_rdasens
+ hafs_4denvar_glbens hafs_3denvar_hybens
)
# EnKF regression test names
-list(APPEND ENKF_REG_TEST_NAMES
- global_enkf
-)
+if(ENKF_MODE MATCHES "^(FV3REG)$")
+ list(APPEND ENKF_REG_TEST_NAMES
+ rrfs_enkf_conv
+ )
+else()
+ list(APPEND ENKF_REG_TEST_NAMES
+ global_enkf
+ )
+endif()
# Add GSI regression tests to list of tests
if(GSICONTROLEXEC)
diff --git a/regression/global_3dvar.sh b/regression/global_3dvar.sh
deleted file mode 100755
index 145cb6212c..0000000000
--- a/regression/global_3dvar.sh
+++ /dev/null
@@ -1,305 +0,0 @@
-set -x
-
-# Set experiment name and analysis date
-
-exp=$jobname
-
-# Set the JCAP resolution which you want.
-export JCAP=48
-export LEVS=127
-export JCAP_B=$JCAP
-
-# Set runtime directories
-tmpdir=$tmpdir/$tmpregdir/${exp}
-
-# Specify GSI fixed field and data directories.
-fixcrtm=${fixcrtm:-$CRTM_FIX}
-
-
-# Set variables used in script
-UNCOMPRESS=gunzip
-CLEAN=NO
-ncp=/bin/cp
-nln="/bin/ln -fs"
-
-
-# Given the requested resolution, set dependent resolution parameters
-if [[ "$JCAP" = "96" ]]; then
- export LONA=384
- export LATA=192
- export DELTIM=1200
-elif [[ "$JCAP" = "48" ]]; then
- export LONA=192
- export LATA=96
- export DELTIM=1200
-else
- echo "INVALID JCAP = $JCAP"
- exit
-fi
-export NLON=$LONA
-export NLAT=$((${LATA}+2))
-
-
-# Given the analysis date, compute the date from which the
-# first guess comes. Extract cycle and set prefix and suffix
-# for guess and observation data files
-gdate=`date +%Y%m%d%H -d "${global_adate:0:8} ${global_adate:8:2} - 6 hours"`
-PDYa=`echo $global_adate | cut -c1-8`
-cyca=`echo $global_adate | cut -c9-10`
-PDYg=`echo $gdate | cut -c1-8`
-cycg=`echo $gdate | cut -c9-10`
-
-dumpobs=gdas
-prefix_obs=${dumpobs}.t${cyca}z
-prefix_ges=gdas.t${cycg}z
-prefix_ens=gdas.t${cycg}z
-suffix=tm00.bufr_d
-
-dumpges=gdas
-COMROOTgfs=$casesdir/gfs/prod
-datobs=$COMROOTgfs/$dumpobs.$PDYa/${cyca}/atmos
-datges=$COMROOTgfs/$dumpges.$PDYg/${cycg}/atmos
-datens=$COMROOTgfs/enkfgdas.$PDYg/${cycg}/atmos
-
-
-# Set up $tmpdir
-rm -rf $tmpdir
-mkdir -p $tmpdir
-cd $tmpdir
-
-# Make gsi namelist
-
-. $scripts/regression_nl_update.sh
-
-SETUP="$SETUP_update"
-GRIDOPTS="$GRIDOPTS_update"
-BKGVERR="$BKGVERR_update"
-ANBKGERR="$ANBKERR_update"
-JCOPTS="$JCOPTS_update"
-STRONGOPTS="$STRONGOPTS_update"
-OBSQC="$OBSQC_update"
-OBSINPUT="$OBSINPUT_update"
-SUPERRAD="$SUPERRAD_update"
-SINGLEOB="$SINGLEOB_update"
-
-if [ "$debug" = ".false." ]; then
- . $scripts/regression_namelists.sh global_3dvar
-else
- . $scripts/regression_namelists_db.sh global_3dvar
-fi
-
-cat << EOF > gsiparm.anl
-
-$gsi_namelist
-
-EOF
-
-# Set fixed files
-# berror = forecast model background error statistics
-# specoef = CRTM spectral coefficients
-# trncoef = CRTM transmittance coefficients
-# emiscoef = CRTM coefficients for IR sea surface emissivity model
-# aerocoef = CRTM coefficients for aerosol effects
-# cldcoef = CRTM coefficients for cloud effects
-# satinfo = text file with information about assimilation of brightness temperatures
-# satangl = angle dependent bias correction file (fixed in time)
-# pcpinfo = text file with information about assimilation of prepcipitation rates
-# ozinfo = text file with information about assimilation of ozone data
-# errtable = text file with obs error for conventional data (optional)
-# convinfo = text file with information about assimilation of conventional data
-# bufrtable= text file ONLY needed for single obs test (oneobstest=.true.)
-# bftab_sst= bufr table for sst ONLY needed for sst retrieval (retrieval=.true.)
-# aeroinfo = text file with information about assimilation of aerosol data
-
-anavinfo=$fixgsi/global_anavinfo.l${LEVS}.txt
-berror=$fixgsi/Big_Endian/global_berror.l${LEVS}y${NLAT}.f77
-locinfo=$fixgsi/global_hybens_info.l${LEVS}.txt
-satinfo=$fixgsi/global_satinfo.txt
-scaninfo=$fixgsi/global_scaninfo.txt
-satangl=$fixgsi/global_satangbias.txt
-pcpinfo=$fixgsi/global_pcpinfo.txt
-ozinfo=$fixgsi/global_ozinfo.txt
-convinfo=$fixgsi/global_convinfo.txt
-vqcdat=$fixgsi/vqctp001.dat
-insituinfo=$fixgsi/global_insituinfo.txt
-errtable=$fixgsi/prepobs_errtable.global
-aeroinfo=$fixgsi/global_aeroinfo.txt
-atmsbeaminfo=$fixgsi/atms_beamwidth.txt
-cloudyinfo=$fixgsi/cloudy_radiance_info.txt
-
-emiscoef_IRwater=$fixcrtm/Nalli.IRwater.EmisCoeff.bin
-emiscoef_IRice=$fixcrtm/NPOESS.IRice.EmisCoeff.bin
-emiscoef_IRland=$fixcrtm/NPOESS.IRland.EmisCoeff.bin
-emiscoef_IRsnow=$fixcrtm/NPOESS.IRsnow.EmisCoeff.bin
-emiscoef_VISice=$fixcrtm/NPOESS.VISice.EmisCoeff.bin
-emiscoef_VISland=$fixcrtm/NPOESS.VISland.EmisCoeff.bin
-emiscoef_VISsnow=$fixcrtm/NPOESS.VISsnow.EmisCoeff.bin
-emiscoef_VISwater=$fixcrtm/NPOESS.VISwater.EmisCoeff.bin
-emiscoef_MWwater=$fixcrtm/FASTEM6.MWwater.EmisCoeff.bin
-aercoef=$fixcrtm/AerosolCoeff.bin
-cldcoef=$fixcrtm/CloudCoeff.bin
-#cldcoef=$fixcrtm/CloudCoeff.GFDLFV3.-109z-1.bin # use with crtm/2.4.0
-
-# Only need this file for single obs test
-bufrtable=$fixgsi/prepobs_prep.bufrtable
-
-# Only need this file for sst retrieval
-bftab_sst=$fixgsi/bufrtab.012
-
-# Copy executable and fixed files to $tmpdir
-if [[ $exp == *"updat"* ]]; then
- $ncp $gsiexec_updat ./gsi.x
-elif [[ $exp == *"contrl"* ]]; then
- $ncp $gsiexec_contrl ./gsi.x
-fi
-
-$ncp $anavinfo ./anavinfo
-$ncp $berror ./berror_stats
-$ncp $locinfo ./hybens_info
-$ncp $satinfo ./satinfo
-$ncp $scaninfo ./scaninfo
-$ncp $pcpinfo ./pcpinfo
-$ncp $ozinfo ./ozinfo
-$ncp $convinfo ./convinfo
-$ncp $vqcdat ./vqctp001.dat
-$ncp $insituinfo ./insituinfo
-$ncp $errtable ./errtable
-$ncp $aeroinfo ./aeroinfo
-$ncp $atmsbeaminfo ./atms_beamwidth.txt
-$ncp $cloudyinfo ./cloudy_radiance_info.txt
-
-$ncp $bufrtable ./prepobs_prep.bufrtable
-$ncp $bftab_sst ./bftab_sstphr
-
-#If using correlated error, get the covariance files
-if grep -q "Rcov" $anavinfo ;
-then
- if ls ${fixgsi}/Rcov* 1> /dev/null 2>&1;
- then
- $ncp ${fixgsi}/Rcov* $tmpdir
-
-# Correlated error utlizes mkl lapack. Found it necesary to fix the
-# number of mkl threads to ensure reproducible results independent
-# of the job configuration.
- export MKL_NUM_THREADS=1
-
- else
- echo "Warning: Satellite error covariance files are missing."
- echo "Check for the required Rcov files in " $ANAVINFO
- exit 1
- fi
-fi
-
-# Copy CRTM coefficient files based on entries in satinfo file
-export CRTM_PATH="./crtm_coeffs/"
-mkdir -p ${CRTM_PATH}
-for file in `awk '{if($1!~"!"){print $1}}' satinfo | sort | uniq` ;do
- $nln $fixcrtm/${file}.SpcCoeff.bin ${CRTM_PATH}/${file}.SpcCoeff.bin
- $nln $fixcrtm/${file}.TauCoeff.bin ${CRTM_PATH}/${file}.TauCoeff.bin
-done
-$nln $fixcrtm/amsua_metop-a_v2.SpcCoeff.bin ${CRTM_PATH}/amsua_metop-a_v2.SpcCoeff.bin
-
-$nln $emiscoef_IRwater ${CRTM_PATH}Nalli.IRwater.EmisCoeff.bin
-$nln $emiscoef_IRice ${CRTM_PATH}NPOESS.IRice.EmisCoeff.bin
-$nln $emiscoef_IRsnow ${CRTM_PATH}NPOESS.IRsnow.EmisCoeff.bin
-$nln $emiscoef_IRland ${CRTM_PATH}NPOESS.IRland.EmisCoeff.bin
-$nln $emiscoef_VISice ${CRTM_PATH}NPOESS.VISice.EmisCoeff.bin
-$nln $emiscoef_VISland ${CRTM_PATH}NPOESS.VISland.EmisCoeff.bin
-$nln $emiscoef_VISsnow ${CRTM_PATH}NPOESS.VISsnow.EmisCoeff.bin
-$nln $emiscoef_VISwater ${CRTM_PATH}NPOESS.VISwater.EmisCoeff.bin
-$nln $emiscoef_MWwater ${CRTM_PATH}FASTEM6.MWwater.EmisCoeff.bin
-$nln $aercoef ${CRTM_PATH}AerosolCoeff.bin
-$nln $cldcoef ${CRTM_PATH}CloudCoeff.bin
-
-# Copy observational data
-$nln $datobs/${prefix_obs}.prepbufr ./prepbufr
-$nln $datobs/${prefix_obs}.prepbufr.acft_profiles ./prepbufr_profl
-$nln $datobs/${prefix_obs}.nsstbufr ./nsstbufr
-$nln $datobs/${prefix_obs}.syndata.tcvitals.tm00 ./tcvitl
-$nln $datobs/${prefix_obs}.gpsro.${suffix} ./gpsrobufr
-$nln $datobs/${prefix_obs}.satwnd.${suffix} ./satwndbufr
-$nln $datobs/${prefix_obs}.hdob.${suffix} ./hdobbufr
-
-$nln $datobs/${prefix_obs}.osbuv8.${suffix} ./sbuvbufr
-$nln $datobs/${prefix_obs}.gome.${suffix} ./gomebufr
-$nln $datobs/${prefix_obs}.omi.${suffix} ./omibufr
-$nln $datobs/${prefix_obs}.mls.${suffix} ./mlsbufr
-$nln $datobs/${prefix_obs}.ompsn8.${suffix} ./ompsnpbufr
-$nln $datobs/${prefix_obs}.ompst8.${suffix} ./ompstcbufr
-$nln $datobs/${prefix_obs}.ompslp.${suffix} ./ompslpbufr
-
-$nln $datobs/${prefix_obs}.goesfv.${suffix} ./gsnd1bufr
-$nln $datobs/${prefix_obs}.hrs3db.${suffix} ./hirs3bufr_db
-$nln $datobs/${prefix_obs}.airsev.${suffix} ./airsbufr
-$nln $datobs/${prefix_obs}.sevcsr.${suffix} ./seviribufr
-$nln $datobs/${prefix_obs}.saphir.${suffix} ./saphirbufr
-$nln $datobs/${prefix_obs}.avcsam.${suffix} ./avhambufr
-$nln $datobs/${prefix_obs}.avcspm.${suffix} ./avhpmbufr
-$nln $datobs/${prefix_obs}.1bhrs4.${suffix} ./hirs4bufr
-$nln $datobs/${prefix_obs}.1bhrs2.${suffix} ./hirs2bufr
-$nln $datobs/${prefix_obs}.1bhrs3.${suffix} ./hirs3bufr
-$nln $datobs/${prefix_obs}.eshrs3.${suffix} ./hirs3bufrears
-$nln $datobs/${prefix_obs}.hrs3db.${suffix} ./hirs3bufr_db
-$nln $datobs/${prefix_obs}.mtiasi.${suffix} ./iasibufr
-$nln $datobs/${prefix_obs}.esiasi.${suffix} ./iasibufrears
-$nln $datobs/${prefix_obs}.iasidb.${suffix} ./iasibufr_db
-$nln $datobs/${prefix_obs}.crisf4.${suffix} ./crisfsbufr
-$nln $datobs/${prefix_obs}.escrsf.${suffix} ./crisfsbufrears
-$nln $datobs/${prefix_obs}.crsfdb.${suffix} ./crisfsbufr_db
-$nln $datobs/${prefix_obs}.ahicsr.${suffix} ./ahibufr
-$nln $datobs/${prefix_obs}.gsrcsr.${suffix} ./abibufr
-$nln $datobs/${prefix_obs}.sstvcw.${suffix} ./sstviirs
-
-$nln $datobs/${prefix_obs}.1bmhs.${suffix} ./mhsbufr
-$nln $datobs/${prefix_obs}.1bmsu.${suffix} ./msubufr
-$nln $datobs/${prefix_obs}.gmi1cr.${suffix} ./gmibufr
-$nln $datobs/${prefix_obs}.ssmit.${suffix} ./ssmitbufr
-$nln $datobs/${prefix_obs}.ssmisu.${suffix} ./ssmisbufr
-$nln $datobs/${prefix_obs}.1bamua.${suffix} ./amsuabufr
-$nln $datobs/${prefix_obs}.esamua.${suffix} ./amsuabufrears
-$nln $datobs/${prefix_obs}.amuadb.${suffix} ./amsuabufr_db
-$nln $datobs/${prefix_obs}.1bamub.${suffix} ./amsubbufr
-$nln $datobs/${prefix_obs}.esamub.${suffix} ./amsubbufrears
-$nln $datobs/${prefix_obs}.amubdb.${suffix} ./amsubbufr_db
-$nln $datobs/${prefix_obs}.atms.${suffix} ./atmsbufr
-$nln $datobs/${prefix_obs}.atmsdb.${suffix} ./atmsbufr_db
-$nln $datobs/${prefix_obs}.esatms.${suffix} ./atmsbufrears
-
-# Do not process
-## $nln $datobs/${prefix_obs}.amsre.${suffix} ./amsrebufr
-## $nln $datobs/${prefix_obs}.amsr2.tm00.bufr_d ./amsr2bufr
-
-# Copy bias correction, atmospheric and surface files
-$nln $datges/${prefix_ges}.abias ./satbias_in
-$nln $datges/${prefix_ges}.abias_pc ./satbias_pc
-$nln $datges/${prefix_ges}.abias_air ./aircftbias_in
-$nln $datges/${prefix_ges}.radstat ./radstat.gdas
-
-member=mem001
-$nln $datens/$member/${prefix_ges}.sfcf003.nc ./sfcf03
-$nln $datens/$member/${prefix_ges}.sfcf006.nc ./sfcf06
-$nln $datens/$member/${prefix_ges}.sfcf009.nc ./sfcf09
-
-$nln $datens/$member/${prefix_ges}.atmf003.nc ./sigf03
-$nln $datens/$member/${prefix_ges}.atmf006.nc ./sigf06
-$nln $datens/$member/${prefix_ges}.atmf009.nc ./sigf09
-
-$nln $datens/${prefix_ens}.sfcf006.ensmean.nc ./sfcf06_anlgrid
-
-
-listdiag=`tar xvf radstat.gdas | cut -d' ' -f2 | grep _ges`
-for type in $listdiag; do
- diag_file=`echo $type | cut -d',' -f1`
- fname=`echo $diag_file | cut -d'.' -f1`
- date=`echo $diag_file | cut -d'.' -f2`
- $UNCOMPRESS $diag_file
- fnameanl=$(echo $fname|sed 's/_ges//g')
- mv $fname.$date $fnameanl
-done
-
-# Run GSI
-echo "run gsi now"
-eval "$APRUN $tmpdir/gsi.x > stdout 2>&1"
-rc=$?
-
-exit $rc
diff --git a/regression/global_4denvar.sh b/regression/global_4denvar.sh
index 7212b819e9..945200eb66 100755
--- a/regression/global_4denvar.sh
+++ b/regression/global_4denvar.sh
@@ -55,14 +55,15 @@ cycg=`echo $gdate | cut -c9-10`
dumpobs=gdas
prefix_obs=${dumpobs}.t${cyca}z
prefix_ges=gdas.t${cycg}z
-prefix_ens=gdas.t${cycg}z
+prefix_ens=enkfgdas.t${cycg}z
suffix=tm00.bufr_d
dumpges=gdas
COMROOTgfs=$casesdir/gfs/prod
-datobs=$COMROOTgfs/$dumpobs.$PDYa/${cyca}/atmos
-datges=$COMROOTgfs/$dumpges.$PDYg/${cycg}/atmos
-datens=$COMROOTgfs/enkfgdas.$PDYg/${cycg}/atmos
+datobs=$COMROOTgfs/$dumpobs.$PDYa/${cyca}/obs
+dathis=$COMROOTgfs/$dumpges.$PDYg/${cycg}/model/atmos/history
+datanl=$COMROOTgfs/gdas.$PDYg/${cycg}/analysis/atmos
+datens=$COMROOTgfs/enkfgdas.$PDYg/${cycg}
# Set up $tmpdir
@@ -127,6 +128,8 @@ errtable=$fixgsi/prepobs_errtable.global
aeroinfo=$fixgsi/global_aeroinfo.txt
atmsbeaminfo=$fixgsi/atms_beamwidth.txt
cloudyinfo=$fixgsi/cloudy_radiance_info.txt
+cris_clddet=$fixgsi/CRIS_CLDDET.NL
+iasi_clddet=$fixgsi/IASI_CLDDET.NL
emiscoef_IRwater=$fixcrtm/Nalli.IRwater.EmisCoeff.bin
emiscoef_IRice=$fixcrtm/NPOESS.IRice.EmisCoeff.bin
@@ -168,6 +171,8 @@ $ncp $errtable ./errtable
$ncp $aeroinfo ./aeroinfo
$ncp $atmsbeaminfo ./atms_beamwidth.txt
$ncp $cloudyinfo ./cloudy_radiance_info.txt
+$ncp $cris_clddet ./CRIS_CLDDET.NL
+$ncp $iasi_clddet ./IASI_CLDDET.NL
$ncp $bufrtable ./prepobs_prep.bufrtable
$ncp $bftab_sst ./bftab_sstphr
@@ -230,17 +235,11 @@ $nln $datobs/${prefix_obs}.ompst8.${suffix} ./ompstcbufr
$nln $datobs/${prefix_obs}.ompslp.${suffix} ./ompslpbufr
$nln $datobs/${prefix_obs}.goesfv.${suffix} ./gsnd1bufr
-$nln $datobs/${prefix_obs}.hrs3db.${suffix} ./hirs3bufr_db
$nln $datobs/${prefix_obs}.airsev.${suffix} ./airsbufr
$nln $datobs/${prefix_obs}.sevcsr.${suffix} ./seviribufr
$nln $datobs/${prefix_obs}.saphir.${suffix} ./saphirbufr
$nln $datobs/${prefix_obs}.avcsam.${suffix} ./avhambufr
$nln $datobs/${prefix_obs}.avcspm.${suffix} ./avhpmbufr
-$nln $datobs/${prefix_obs}.1bhrs4.${suffix} ./hirs4bufr
-$nln $datobs/${prefix_obs}.1bhrs2.${suffix} ./hirs2bufr
-$nln $datobs/${prefix_obs}.1bhrs3.${suffix} ./hirs3bufr
-$nln $datobs/${prefix_obs}.eshrs3.${suffix} ./hirs3bufrears
-$nln $datobs/${prefix_obs}.hrs3db.${suffix} ./hirs3bufr_db
$nln $datobs/${prefix_obs}.mtiasi.${suffix} ./iasibufr
$nln $datobs/${prefix_obs}.esiasi.${suffix} ./iasibufrears
$nln $datobs/${prefix_obs}.iasidb.${suffix} ./iasibufr_db
@@ -271,28 +270,28 @@ $nln $datobs/${prefix_obs}.esatms.${suffix} ./atmsbufrears
## $nln $datobs/${prefix_obs}.amsr2.tm00.bufr_d ./amsr2bufr
# Copy bias correction, atmospheric and surface files
-$nln $datges/${prefix_ges}.abias ./satbias_in
-$nln $datges/${prefix_ges}.abias_pc ./satbias_pc
-$nln $datges/${prefix_ges}.abias_air ./aircftbias_in
-$nln $datges/${prefix_ges}.radstat ./radstat.gdas
-
-$nln $datges/${prefix_ges}.sfcf003.nc ./sfcf03
-$nln $datges/${prefix_ges}.sfcf004.nc ./sfcf04
-$nln $datges/${prefix_ges}.sfcf005.nc ./sfcf05
-$nln $datges/${prefix_ges}.sfcf006.nc ./sfcf06
-$nln $datges/${prefix_ges}.sfcf007.nc ./sfcf07
-$nln $datges/${prefix_ges}.sfcf008.nc ./sfcf08
-$nln $datges/${prefix_ges}.sfcf009.nc ./sfcf09
-
-$nln $datges/${prefix_ges}.atmf003.nc ./sigf03
-$nln $datges/${prefix_ges}.atmf004.nc ./sigf04
-$nln $datges/${prefix_ges}.atmf005.nc ./sigf05
-$nln $datges/${prefix_ges}.atmf006.nc ./sigf06
-$nln $datges/${prefix_ges}.atmf007.nc ./sigf07
-$nln $datges/${prefix_ges}.atmf008.nc ./sigf08
-$nln $datges/${prefix_ges}.atmf009.nc ./sigf09
-
-$nln $datens/${prefix_ens}.sfcf006.ensmean.nc ./sfcf06_anlgrid
+$nln $datanl/${prefix_ges}.abias ./satbias_in
+$nln $datanl/${prefix_ges}.abias_pc ./satbias_pc
+$nln $datanl/${prefix_ges}.abias_air ./aircftbias_in
+$nln $datanl/${prefix_ges}.radstat ./radstat.gdas
+
+$nln $dathis/${prefix_ges}.sfcf003.nc ./sfcf03
+$nln $dathis/${prefix_ges}.sfcf004.nc ./sfcf04
+$nln $dathis/${prefix_ges}.sfcf005.nc ./sfcf05
+$nln $dathis/${prefix_ges}.sfcf006.nc ./sfcf06
+$nln $dathis/${prefix_ges}.sfcf007.nc ./sfcf07
+$nln $dathis/${prefix_ges}.sfcf008.nc ./sfcf08
+$nln $dathis/${prefix_ges}.sfcf009.nc ./sfcf09
+
+$nln $dathis/${prefix_ges}.atmf003.nc ./sigf03
+$nln $dathis/${prefix_ges}.atmf004.nc ./sigf04
+$nln $dathis/${prefix_ges}.atmf005.nc ./sigf05
+$nln $dathis/${prefix_ges}.atmf006.nc ./sigf06
+$nln $dathis/${prefix_ges}.atmf007.nc ./sigf07
+$nln $dathis/${prefix_ges}.atmf008.nc ./sigf08
+$nln $dathis/${prefix_ges}.atmf009.nc ./sigf09
+
+$nln $datens/ensstat/model/atmos/history/${prefix_ens}.sfcf006.ensmean.nc ./sfcf06_anlgrid
export ENS_PATH='./ensemble_data/'
mkdir -p ${ENS_PATH}
@@ -302,7 +301,7 @@ for fh in $flist; do
imem=1
while [[ $imem -le $NMEM_ENKF ]]; do
member="mem"`printf %03i $imem`
- $nln $datens/$member/$sigens ${ENS_PATH}sigf${fh}_ens_${member}
+ $nln $datens/$member/model/atmos/history/$sigens ${ENS_PATH}sigf${fh}_ens_${member}
(( imem = $imem + 1 ))
done
done
diff --git a/regression/global_4dvar.sh b/regression/global_4dvar.sh
deleted file mode 100755
index ec2a8396e0..0000000000
--- a/regression/global_4dvar.sh
+++ /dev/null
@@ -1,338 +0,0 @@
-set -x
-
-# Set experiment name and analysis date
-
-exp=$jobname
-
-# Set the JCAP resolution which you want.
-export JCAP=48
-export LEVS=127
-export JCAP_B=48
-
-# Set runtime directories
-tmpdir=$tmpdir/$tmpregdir/${exp}
-
-# Specify GSI fixed field and data directories.
-fixcrtm=${fixcrtm:-$CRTM_FIX}
-
-
-# Set variables used in script
-UNCOMPRESS=gunzip
-CLEAN=NO
-ncp=/bin/cp
-nln="/bin/ln -fs"
-
-
-# Given the requested resolution, set dependent resolution parameters
-if [[ "$JCAP" = "96" ]]; then
- export LONA=384
- export LATA=192
- export DELTIM=1200
-elif [[ "$JCAP" = "48" ]]; then
- export LONA=192
- export LATA=96
- export DELTIM=1200
-else
- echo "INVALID JCAP = $JCAP"
- exit
-fi
-export NLON=$LONA
-export NLAT=$((${LATA}+2))
-
-
-# Given the analysis date, compute the date from which the
-# first guess comes. Extract cycle and set prefix and suffix
-# for guess and observation data files
-gdate=`date +%Y%m%d%H -d "${global_adate:0:8} ${global_adate:8:2} - 6 hours"`
-PDYa=`echo $global_adate | cut -c1-8`
-cyca=`echo $global_adate | cut -c9-10`
-PDYg=`echo $gdate | cut -c1-8`
-cycg=`echo $gdate | cut -c9-10`
-
-dumpobs=gdas
-prefix_obs=${dumpobs}.t${cyca}z
-prefix_ges=gdas.t${cycg}z
-prefix_ens=gdas.t${cycg}z
-suffix=tm00.bufr_d
-
-dumpges=gdas
-COMROOTgfs=$casesdir/gfs/prod
-datobs=$COMROOTgfs/$dumpobs.$PDYa/${cyca}/atmos
-datges=$COMROOTgfs/$dumpges.$PDYg/${cycg}/atmos
-datens=$COMROOTgfs/enkfgdas.$PDYg/${cycg}/atmos
-
-
-# Set up $tmpdir
-rm -rf $tmpdir
-mkdir -p $tmpdir
-cd $tmpdir
-
-# Make gsi namelist
-
-SETUP=""
-GRIDOPTS=""
-BKGVERR=""
-ANBKGERR=""
-JCOPTS=""
-STRONGOPTS=""
-OBSQC=""
-OBSINPUT=""
-SUPERRAD=""
-SINGLEOB=""
-
-
-# Set fixed files
-# berror = forecast model background error statistics
-# specoef = CRTM spectral coefficients
-# trncoef = CRTM transmittance coefficients
-# emiscoef = CRTM coefficients for IR sea surface emissivity model
-# aerocoef = CRTM coefficients for aerosol effects
-# cldcoef = CRTM coefficients for cloud effects
-# satinfo = text file with information about assimilation of brightness temperatures
-# satangl = angle dependent bias correction file (fixed in time)
-# pcpinfo = text file with information about assimilation of prepcipitation rates
-# ozinfo = text file with information about assimilation of ozone data
-# errtable = text file with obs error for conventional data (optional)
-# convinfo = text file with information about assimilation of conventional data
-# bufrtable= text file ONLY needed for single obs test (oneobstest=.true.)
-# bftab_sst= bufr table for sst ONLY needed for sst retrieval (retrieval=.true.)
-# aeroinfo = text file with information about assimilation of aerosol data
-
-anavinfo=$fixgsi/global_anavinfo.l${LEVS}.txt
-berror=$fixgsi/Big_Endian/global_berror.l${LEVS}y${NLAT}.f77
-locinfo=$fixgsi/global_hybens_info.l${LEVS}.txt
-satinfo=$fixgsi/global_satinfo.txt
-scaninfo=$fixgsi/global_scaninfo.txt
-satangl=$fixgsi/global_satangbias.txt
-pcpinfo=$fixgsi/global_pcpinfo.txt
-ozinfo=$fixgsi/global_ozinfo.txt
-convinfo=$fixgsi/global_convinfo.txt
-vqcdat=$fixgsi/vqctp001.dat
-insituinfo=$fixgsi/global_insituinfo.txt
-errtable=$fixgsi/prepobs_errtable.global
-aeroinfo=$fixgsi/global_aeroinfo.txt
-atmsbeaminfo=$fixgsi/atms_beamwidth.txt
-cloudyinfo=$fixgsi/cloudy_radiance_info.txt
-
-emiscoef_IRwater=$fixcrtm/Nalli.IRwater.EmisCoeff.bin
-emiscoef_IRice=$fixcrtm/NPOESS.IRice.EmisCoeff.bin
-emiscoef_IRland=$fixcrtm/NPOESS.IRland.EmisCoeff.bin
-emiscoef_IRsnow=$fixcrtm/NPOESS.IRsnow.EmisCoeff.bin
-emiscoef_VISice=$fixcrtm/NPOESS.VISice.EmisCoeff.bin
-emiscoef_VISland=$fixcrtm/NPOESS.VISland.EmisCoeff.bin
-emiscoef_VISsnow=$fixcrtm/NPOESS.VISsnow.EmisCoeff.bin
-emiscoef_VISwater=$fixcrtm/NPOESS.VISwater.EmisCoeff.bin
-emiscoef_MWwater=$fixcrtm/FASTEM6.MWwater.EmisCoeff.bin
-aercoef=$fixcrtm/AerosolCoeff.bin
-cldcoef=$fixcrtm/CloudCoeff.bin
-#cldcoef=$fixcrtm/CloudCoeff.GFDLFV3.-109z-1.bin # use with crtm/2.4.0
-
-# Only need this file for single obs test
-bufrtable=$fixgsi/prepobs_prep.bufrtable
-
-# Only need this file for sst retrieval
-bftab_sst=$fixgsi/bufrtab.012
-
-# Copy executable and fixed files to $tmpdir
-if [[ $exp == *"updat"* ]]; then
- $ncp $gsiexec_updat ./gsi.x
-elif [[ $exp == *"contrl"* ]]; then
- $ncp $gsiexec_contrl ./gsi.x
-fi
-
-$ncp $anavinfo ./anavinfo
-$ncp $berror ./berror_stats
-$ncp $locinfo ./hybens_info
-$ncp $satinfo ./satinfo
-$ncp $scaninfo ./scaninfo
-##$ncp $satangl ./satbias_angle
-$ncp $pcpinfo ./pcpinfo
-$ncp $ozinfo ./ozinfo
-$ncp $convinfo ./convinfo
-$ncp $vqcdat ./vqctp001.dat
-$ncp $insituinfo ./insituinfo
-$ncp $errtable ./errtable
-$ncp $aeroinfo ./aeroinfo
-$ncp $atmsbeaminfo ./atms_beamwidth.txt
-$ncp $cloudyinfo ./cloudy_radiance_info.txt
-
-$ncp $bufrtable ./prepobs_prep.bufrtable
-$ncp $bftab_sst ./bftab_sstphr
-
-#If using correlated error, get the covariance files
-if grep -q "Rcov" $anavinfo ;
-then
- if ls ${fixgsi}/Rcov* 1> /dev/null 2>&1;
- then
- $ncp ${fixgsi}/Rcov* $tmpdir
-
-# Correlated error utlizes mkl lapack. Found it necesary to fix the
-# number of mkl threads to ensure reproducible results independent
-# of the job configuration.
- export MKL_NUM_THREADS=1
-
- else
- echo "Warning: Satellite error covariance files are missing."
- echo "Check for the required Rcov files in " $ANAVINFO
- exit 1
- fi
-fi
-
-# Copy CRTM coefficient files based on entries in satinfo file
-export CRTM_PATH="./crtm_coeffs/"
-mkdir -p ${CRTM_PATH}
-for file in `awk '{if($1!~"!"){print $1}}' satinfo | sort | uniq` ;do
- $nln $fixcrtm/${file}.SpcCoeff.bin ${CRTM_PATH}/${file}.SpcCoeff.bin
- $nln $fixcrtm/${file}.TauCoeff.bin ${CRTM_PATH}/${file}.TauCoeff.bin
-done
-$nln $fixcrtm/amsua_metop-a_v2.SpcCoeff.bin ${CRTM_PATH}/amsua_metop-a_v2.SpcCoeff.bin
-
-$nln $emiscoef_IRwater ${CRTM_PATH}Nalli.IRwater.EmisCoeff.bin
-$nln $emiscoef_IRice ${CRTM_PATH}NPOESS.IRice.EmisCoeff.bin
-$nln $emiscoef_IRsnow ${CRTM_PATH}NPOESS.IRsnow.EmisCoeff.bin
-$nln $emiscoef_IRland ${CRTM_PATH}NPOESS.IRland.EmisCoeff.bin
-$nln $emiscoef_VISice ${CRTM_PATH}NPOESS.VISice.EmisCoeff.bin
-$nln $emiscoef_VISland ${CRTM_PATH}NPOESS.VISland.EmisCoeff.bin
-$nln $emiscoef_VISsnow ${CRTM_PATH}NPOESS.VISsnow.EmisCoeff.bin
-$nln $emiscoef_VISwater ${CRTM_PATH}NPOESS.VISwater.EmisCoeff.bin
-$nln $emiscoef_MWwater ${CRTM_PATH}FASTEM6.MWwater.EmisCoeff.bin
-$nln $aercoef ${CRTM_PATH}AerosolCoeff.bin
-$nln $cldcoef ${CRTM_PATH}CloudCoeff.bin
-
-# Copy observational data
-$nln $datobs/${prefix_obs}.prepbufr ./prepbufr
-$nln $datobs/${prefix_obs}.prepbufr.acft_profiles ./prepbufr_profl
-$nln $datobs/${prefix_obs}.nsstbufr ./nsstbufr
-$nln $datobs/${prefix_obs}.syndata.tcvitals.tm00 ./tcvitl
-$nln $datobs/${prefix_obs}.gpsro.${suffix} ./gpsrobufr
-$nln $datobs/${prefix_obs}.satwnd.${suffix} ./satwndbufr
-$nln $datobs/${prefix_obs}.hdob.${suffix} ./hdobbufr
-
-$nln $datobs/${prefix_obs}.osbuv8.${suffix} ./sbuvbufr
-$nln $datobs/${prefix_obs}.gome.${suffix} ./gomebufr
-$nln $datobs/${prefix_obs}.omi.${suffix} ./omibufr
-$nln $datobs/${prefix_obs}.mls.${suffix} ./mlsbufr
-$nln $datobs/${prefix_obs}.ompsn8.${suffix} ./ompsnpbufr
-$nln $datobs/${prefix_obs}.ompst8.${suffix} ./ompstcbufr
-$nln $datobs/${prefix_obs}.ompslp.${suffix} ./ompslpbufr
-
-$nln $datobs/${prefix_obs}.goesfv.${suffix} ./gsnd1bufr
-$nln $datobs/${prefix_obs}.hrs3db.${suffix} ./hirs3bufr_db
-$nln $datobs/${prefix_obs}.airsev.${suffix} ./airsbufr
-$nln $datobs/${prefix_obs}.sevcsr.${suffix} ./seviribufr
-$nln $datobs/${prefix_obs}.saphir.${suffix} ./saphirbufr
-$nln $datobs/${prefix_obs}.avcsam.${suffix} ./avhambufr
-$nln $datobs/${prefix_obs}.avcspm.${suffix} ./avhpmbufr
-$nln $datobs/${prefix_obs}.1bhrs4.${suffix} ./hirs4bufr
-$nln $datobs/${prefix_obs}.1bhrs2.${suffix} ./hirs2bufr
-$nln $datobs/${prefix_obs}.1bhrs3.${suffix} ./hirs3bufr
-$nln $datobs/${prefix_obs}.eshrs3.${suffix} ./hirs3bufrears
-$nln $datobs/${prefix_obs}.hrs3db.${suffix} ./hirs3bufr_db
-$nln $datobs/${prefix_obs}.mtiasi.${suffix} ./iasibufr
-$nln $datobs/${prefix_obs}.esiasi.${suffix} ./iasibufrears
-$nln $datobs/${prefix_obs}.iasidb.${suffix} ./iasibufr_db
-$nln $datobs/${prefix_obs}.crisf4.${suffix} ./crisfsbufr
-$nln $datobs/${prefix_obs}.escrsf.${suffix} ./crisfsbufrears
-$nln $datobs/${prefix_obs}.crsfdb.${suffix} ./crisfsbufr_db
-$nln $datobs/${prefix_obs}.ahicsr.${suffix} ./ahibufr
-$nln $datobs/${prefix_obs}.gsrcsr.${suffix} ./abibufr
-$nln $datobs/${prefix_obs}.sstvcw.${suffix} ./sstviirs
-
-$nln $datobs/${prefix_obs}.1bmhs.${suffix} ./mhsbufr
-$nln $datobs/${prefix_obs}.1bmsu.${suffix} ./msubufr
-$nln $datobs/${prefix_obs}.gmi1cr.${suffix} ./gmibufr
-$nln $datobs/${prefix_obs}.ssmit.${suffix} ./ssmitbufr
-$nln $datobs/${prefix_obs}.ssmisu.${suffix} ./ssmisbufr
-$nln $datobs/${prefix_obs}.1bamua.${suffix} ./amsuabufr
-$nln $datobs/${prefix_obs}.esamua.${suffix} ./amsuabufrears
-$nln $datobs/${prefix_obs}.amuadb.${suffix} ./amsuabufr_db
-$nln $datobs/${prefix_obs}.1bamub.${suffix} ./amsubbufr
-$nln $datobs/${prefix_obs}.esamub.${suffix} ./amsubbufrears
-$nln $datobs/${prefix_obs}.amubdb.${suffix} ./amsubbufr_db
-$nln $datobs/${prefix_obs}.atms.${suffix} ./atmsbufr
-$nln $datobs/${prefix_obs}.atmsdb.${suffix} ./atmsbufr_db
-$nln $datobs/${prefix_obs}.esatms.${suffix} ./atmsbufrears
-
-# Do not process
-## $nln $datobs/${prefix_obs}.amsre.${suffix} ./amsrebufr
-## $nln $datobs/${prefix_obs}.amsr2.tm00.bufr_d ./amsr2bufr
-
-# Copy bias correction, atmospheric and surface files
-##$nln $datges/${prefix_ges}.abias ./satbias_in
-##$nln $datges/${prefix_ges}.abias_pc ./satbias_pc
-##$nln $datges/${prefix_ges}.abias_air ./aircftbias_in
-
-
-#$nln $datges/${prefix_ges}.abias.4dvar ./satbias_in
-$nln $datges/${prefix_ges}.satang.4dvar ./satbias_angle
-
-$nln $datges/${prefix_ges}.radstat ./radstat.gdas
-
-member=mem001
-$nln $datens/$member/${prefix_ges}.sfcf003.nc ./sfcf03
-##$nln $datens/$member/${prefix_ges}.sfcf004.nc ./sfcf04
-##$nln $datens/$member/${prefix_ges}.sfcf005.nc ./sfcf05
-$nln $datens/$member/${prefix_ges}.sfcf006.nc ./sfcf06
-##$nln $datens/$member/${prefix_ges}.sfcf007.nc ./sfcf07
-##$nln $datens/$member/${prefix_ges}.sfcf008.nc ./sfcf08
-$nln $datens/$member/${prefix_ges}.sfcf009.nc ./sfcf09
-
-$nln $datens/$member/${prefix_ges}.atmf003.nc ./sigf03
-##$nln $datens/$member/${prefix_ges}.atmf004.nc ./sigf04
-##$nln $datens/$member/${prefix_ges}.atmf005.nc ./sigf05
-$nln $datens/$member/${prefix_ges}.atmf006.nc ./sigf06
-##$nln $datens/$member/${prefix_ges}.atmf007.nc ./sigf07
-##$nln $datens/$member/${prefix_ges}.atmf008.nc ./sigf08
-$nln $datens/$member/${prefix_ges}.atmf009.nc ./sigf09
-
-$nln $datens/${prefix_ens}.sfcf006.ensmean.nc ./sfcf06_anlgrid
-
-listdiag=`tar xvf radstat.gdas | cut -d' ' -f2 | grep _ges`
-for type in $listdiag; do
- diag_file=`echo $type | cut -d',' -f1`
- fname=`echo $diag_file | cut -d'.' -f1`
- date=`echo $diag_file | cut -d'.' -f2`
- $UNCOMPRESS $diag_file
- fnameanl=$(echo $fname|sed 's/_ges//g')
- mv $fname.$date $fnameanl
-done
-
-
-# Run GSI in observer mode
-SETUP="l4dvar=.true.,jiterstart=1,lobserver=.true.,iwrtinc=1,nhr_assimilation=6,nhr_obsbin=1,"
-if [ "$debug" = ".false." ]; then
- . $scripts/regression_namelists.sh global_lanczos
-else
- . $scripts/regression_namelists_db.sh global_lanczos
-fi
-rm gsiparm.anl
-cat << EOF > gsiparm.anl
-$gsi_namelist
-EOF
-cp gsiparm.anl gsiparm.anl.obsvr
-
-echo "run gsi now"
-eval "$APRUN $tmpdir/gsi.x < gsiparm.anl > stdout.obsvr 2>&1"
-rc=$?
-
-# Run gsi identity model 4dvar under Parallel Operating Environment (poe) on NCEP IBM
-rm -f siganl sfcanl.gsi satbias_out fort.2*
-rm -rf dir.0*
-
-# Create namelist for identity model 4dvar run
-SETUP="l4dvar=.true.,jiterstart=1,nhr_assimilation=6,nhr_obsbin=1,idmodel=.true.,iwrtinc=1,lanczosave=.true.,"
-if [ "$debug" = ".false." ]; then
- . $scripts/regression_namelists.sh global_lanczos
-else
- . $scripts/regression_namelists_db.sh global_lanczos
-fi
-rm gsiparm.anl
-cat < gsiparm.anl
-$gsi_namelist
-EOF
-
-echo "run gsi now"
-eval "$APRUN $tmpdir/gsi.x < gsiparm.anl > stdout 2>&1"
-rc=$?
-
-exit $rc
diff --git a/regression/global_enkf.sh b/regression/global_enkf.sh
index e458c5830d..a35f8d109f 100755
--- a/regression/global_enkf.sh
+++ b/regression/global_enkf.sh
@@ -51,17 +51,14 @@ cyca=`echo $global_adate | cut -c9-10`
PDYg=`echo $gdate | cut -c1-8`
cycg=`echo $gdate | cut -c9-10`
-dumpobs=gdas
-prefix_obs=${dumpobs}.t${cyca}z
-prefix_ges=gdas.t${cycg}z
-prefix_ens=gdas.t${cycg}z
+prefix_obs=enkfgdas.t${cyca}z
+prefix_ens=enkfgdas.t${cycg}z
suffix=tm00.bufr_d
dumpges=gdas
COMROOTgfs=$casesdir/gfs/prod
-datobs=$COMROOTgfs/enkfgdas.$PDYa/${cyca}/atmos
-datges=$COMROOTgfs/$dumpges.$PDYg/${cycg}/atmos
-datens=$COMROOTgfs/enkfgdas.$PDYg/${cycg}/atmos
+datobs=$COMROOTgfs/enkfgdas.$PDYa/${cyca}/ensstat/analysis/atmos
+datens=$COMROOTgfs/enkfgdas.$PDYg/${cycg}
# Set up $tmpdir
@@ -166,19 +163,19 @@ nfhrs=`echo $IAUFHRS_ENKF | sed 's/,/ /g'`
for fhr in $nfhrs; do
for imem in $(seq 1 $NMEM_ENKF); do
memchar="mem"$(printf %03i $imem)
- $nln $datens/$memchar/${prefix_ens}.atmf00${fhr}.nc sfg_${global_adate}_fhr0${fhr}_${memchar}
+ $nln $datens/$memchar/model/atmos/history/${prefix_ens}.atmf00${fhr}.nc sfg_${global_adate}_fhr0${fhr}_${memchar}
if [ $cnvw_option = ".true." ]; then
- $nln $datens/$memchar/${prefix_ens}sfcf00${fhr}.nc sfgsfc_${global_adate}_fhr0${fhr}_${memchar}
+ $nln $datens/$memchar/model/atmos/history/${prefix_ens}sfcf00${fhr}.nc sfgsfc_${global_adate}_fhr0${fhr}_${memchar}
fi
(( imem = $imem + 1 ))
done
- $nln $datens/${prefix_ens}.atmf00${fhr}.ensmean.nc sfg_${global_adate}_fhr0${fhr}_ensmean
+ $nln $datens/ensstat/model/atmos/history/${prefix_ens}.atmf00${fhr}.ensmean.nc sfg_${global_adate}_fhr0${fhr}_ensmean
if [ $cnvw_option = ".true." ]; then
$nln $datens/${prefix_ens}.sfcf00${fhr}.ensmean.nc sfgsfc_${global_adate}_fhr0${fhr}_ensmean
fi
done
-$nln $datobs/${prefix_obs}.abias_int ./satbias_in
+$nln $datobs/${prefix_obs}.abias_int.ensmean ./satbias_in
cd $tmpdir
diff --git a/regression/hafs_3denvar_hybens.sh b/regression/hafs_3denvar_hybens.sh
new file mode 100755
index 0000000000..fa128b8efa
--- /dev/null
+++ b/regression/hafs_3denvar_hybens.sh
@@ -0,0 +1,451 @@
+set -x
+# Set variables used in script
+# CLEAN up $tmpdir when finished (YES=remove, NO=leave alone)
+# ncp is cp replacement, currently keep as /bin/cp
+
+UNCOMPRESS=gunzip
+CLEAN=NO
+ncp=/bin/cp
+nln="/bin/ln -sf"
+
+# HAFS test cases set up
+RUN_FGAT=YES # use FGAT or not
+RUN_ENSDA=YES
+l4densvar=.false.
+nhr_obsbin=-1
+l_both_fv3sar_gfs_ens=.true.
+n_ens_gfs=5
+n_ens_fv3sar=5
+
+#
+# Set experiment name
+#
+exp=$jobname
+
+#-----------------------------------------------------------------------
+#
+# Extract from ADATE the starting year, month, day, and hour of the
+# forecast. These are needed below for various operations.
+#
+#-----------------------------------------------------------------------
+#
+adate=${hafs_envar_adate}
+YYYYMMDDHH=$(date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2}")
+JJJ=$(date +%j -d "${adate:0:8} ${adate:8:2}")
+
+YYYY=${YYYYMMDDHH:0:4}
+MM=${YYYYMMDDHH:4:2}
+DD=${YYYYMMDDHH:6:2}
+HH=${YYYYMMDDHH:8:2}
+YYYYMMDD=${YYYYMMDDHH:0:8}
+PDY=${YYYYMMDD}
+cyc=${HH}
+# prior date and hour
+adateprior=`date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2} - 6 hours"`
+
+ymdprior=$(echo ${adateprior} | cut -c1-8)
+hhprior=$(echo ${adateprior} | cut -c9-10)
+
+CDATEtm03=`date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2} - 3 hours"`
+ymdtm03=$(echo ${CDATEtm03} | cut -c1-8)
+hhtm03=$(echo ${CDATEtm03} | cut -c9-10)
+
+CDATEtp03=`date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2} + 3 hours"`
+ymdtp03=$(echo ${CDATEtp03} | cut -c1-8)
+hhtp03=$(echo ${CDATEtp03} | cut -c9-10)
+
+#
+#-----------------------------------------------------------------------
+#
+# go to working directory and save directory.
+# define fix and background path
+#
+#-----------------------------------------------------------------------
+# Set runtime and save directories
+tmpdir=$tmpdir/tmpreg_hafs_3denvar_hybens/${exp}
+savdir=$savdir/outreg_hafs_3denvar_hybens/${exp}
+
+# Set up $tmpdir
+rm -rf $tmpdir
+mkdir -p $tmpdir
+chgrp rstprod $tmpdir
+chmod 750 $tmpdir
+cd $tmpdir
+
+bkpath=${hafs_envar_ges}
+fixcrtm=${fixcrtm:-$CRTM_FIX}
+
+################################################################
+##### input data and fix directory #######################
+inputdata=${hafs_envar_ges}
+COMINgdas=${hafs_envar_ens}
+COMINobs=${hafs_envar_obs}
+COMINgfs=${hafs_envar_obs}
+WORKhafs=${hafs_envar_obs}
+##########################################################
+
+# use FGAT or not
+if [ ${RUN_FGAT} = "YES" ]; then
+ ln -sf ${inputdata}/coupler.res_03 .
+ ln -sf ${inputdata}/fv3_akbk_03 .
+ ln -sf ${inputdata}/fv3_sfcdata_03 .
+ ln -sf ${inputdata}/fv3_srfwnd_03 .
+ ln -sf ${inputdata}/fv3_dynvars_03 .
+ ln -sf ${inputdata}/fv3_tracer_03 .
+
+ ln -sf ${inputdata}/coupler.res_09 .
+ ln -sf ${inputdata}/fv3_akbk_09 .
+ ln -sf ${inputdata}/fv3_sfcdata_09 .
+ ln -sf ${inputdata}/fv3_srfwnd_09 .
+ ln -sf ${inputdata}/fv3_dynvars_09 .
+ ln -sf ${inputdata}/fv3_tracer_09 .
+fi
+
+# copy background and grib configuration files
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.coupler.res ./coupler.res
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.fv_core.res.nc ./fv3_akbk
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.sfc_data.nc ./fv3_sfcdata
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.fv_srf_wnd.res.tile1.nc ./fv3_srfwnd
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.fv_core.res.tile1.nc ./fv3_dynvars
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.fv_tracer.res.tile1.nc ./fv3_tracer
+
+cp ${bkpath}/oro_data.nc ./fv3_oro_data
+cp ${bkpath}/atmos_static.nc ./fv3_atmos_static
+cp ${bkpath}/grid_spec.nc ./fv3_grid_spec
+
+# create ensemble member file list
+if [ ${RUN_ENSDA} != "YES" ] || [ $l_both_fv3sar_gfs_ens = .true. ]; then
+# Link gdas ensemble members
+ mkdir -p ensemble_data
+ GSUFFIX=${GSUFFIX:-.nc}
+ if [ ${l4densvar:-.false.} = ".true." ]; then
+ fhrs="03 06 09"
+ else
+ fhrs="06"
+ fi
+ for fhh in $fhrs; do
+ rm -f filelist${fhh}
+ for mem in $(seq -f '%03g' 1 ${n_ens_gfs}); do
+ if [ -s ${COMINgdas}/enkfgdas.${ymdprior}/${hhprior}/atmos/mem${mem}/gdas.t${hhprior}z.atmf0${fhh}s${GSUFFIX:-.nc} ]; then
+ ${nln} ${COMINgdas}/enkfgdas.${ymdprior}/${hhprior}/atmos/mem${mem}/gdas.t${hhprior}z.atmf0${fhh}s${GSUFFIX:-.nc} ./ensemble_data/enkfgdas.${ymdprior}${hhprior}.atmf0${fhh}_ens_${mem}
+ elif [ -s ${COMINgdas}/enkfgdas.${ymdprior}/${hhprior}/atmos/mem${mem}/gdas.t${hhprior}z.atmf0${fhh}${GSUFFIX:-.nc} ]; then
+ ${nln} ${COMINgdas}/enkfgdas.${ymdprior}/${hhprior}/atmos/mem${mem}/gdas.t${hhprior}z.atmf0${fhh}${GSUFFIX:-.nc} ./ensemble_data/enkfgdas.${ymdprior}${hhprior}.atmf0${fhh}_ens_${mem}
+ fi
+ echo "./ensemble_data/enkfgdas.${ymdprior}${hhprior}.atmf0${fhh}_ens_${mem}" >> filelist${fhh}
+ done
+ done
+fi
+
+if [ ${RUN_ENSDA} = "YES" ]; then
+ for mem in $(seq -f '%03g' 1 ${n_ens_fv3sar})
+ do
+ RESTARTens=${inputdata}
+ fhh="06"
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-coupler.res .
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-fv3_akbk .
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-fv3_sfcdata .
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-fv3_srfwnd .
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-fv3_dynvars .
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-fv3_tracer .
+ if [ ! -s ./fv3_ens_grid_spec ]; then
+ ln -sf ${RESTARTens}/grid_spec.nc ./fv3_ens_grid_spec
+ fi
+ if [ ${l4densvar:-.false.} = ".true." ]; then
+ export ENS_NSTARTHR=3
+ fhh="03"
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-coupler.res .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_akbk .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_sfcdata .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_srfwnd .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_dynvars .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_tracer .
+ fhh="09"
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-coupler.res .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_akbk .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_sfcdata .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_srfwnd .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_dynvars .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_tracer .
+ fi
+ done
+fi
+if [ ${RUN_ENSDA} != "YES" ]; then
+ export N_ENS=${n_ens_gfs}
+ export BETA_S0=${BETA_S0:-0.2}
+ export GRID_RATIO_ENS=1
+ export REGIONAL_ENSEMBLE_OPTION=1
+elif [ ${RUN_ENSDA} = "YES" ]; then
+ if [ $l_both_fv3sar_gfs_ens = .false. ]; then
+ export N_ENS=${n_ens_fv3sar}
+ export BETA_S0=${BETA_S0:-0.0}
+ export GRID_RATIO_ENS=2
+ export grid_ratio_fv3_regional=2
+ export REGIONAL_ENSEMBLE_OPTION=5
+ elif [ $l_both_fv3sar_gfs_ens = .true. ]; then
+ export N_ENS=$((${n_ens_gfs} + ${n_ens_fv3sar}))
+ export BETA_S0=${BETA_S0:-0.0}
+ export GRID_RATIO_ENS=2
+ export grid_ratio_fv3_regional=2
+ export REGIONAL_ENSEMBLE_OPTION=5
+ fi
+fi
+
+#-----------------------------------------------------------------------
+#
+# link observation files
+# copy observation files to working directory
+#
+#-----------------------------------------------------------------------
+
+# Link GFS/GDAS input and observation files
+COMIN_OBS=${COMIN_OBS:-${COMINobs}}
+COMIN_GFS=${COMIN_GFS:-${COMINgfs}}
+
+OPREFIX=${OPREFIX:-"gfs.t${cyc}z."}
+OSUFFIX=${OSUFFIX:-""}
+PREPQC=${PREPQC:-${COMIN_OBS}/${OPREFIX}prepbufr${OSUFFIX}}
+PREPQCPF=${PREPQCPF:-${COMIN_OBS}/${OPREFIX}prepbufr.acft_profiles${OSUFFIX}}
+NSSTBF=${NSSTBF:-${COMIN_OBS}/${OPREFIX}nsstbufr${OSUFFIX}}
+SATWND=${SATWND:-${COMIN_OBS}/${OPREFIX}satwnd.tm00.bufr_d${OSUFFIX}}
+SATWHR=${SATWHR:-${COMIN_OBS}/${OPREFIX}satwhr.tm00.bufr_d${OSUFFIX}}
+OSCATBF=${OSCATBF:-${COMIN_OBS}/${OPREFIX}oscatw.tm00.bufr_d${OSUFFIX}}
+RAPIDSCATBF=${RAPIDSCATBF:-${COMIN_OBS}/${OPREFIX}rapidscatw.tm00.bufr_d${OSUFFIX}}
+GSNDBF=${GSNDBF:-${COMIN_OBS}/${OPREFIX}goesnd.tm00.bufr_d${OSUFFIX}}
+GSNDBF1=${GSNDBF1:-${COMIN_OBS}/${OPREFIX}goesfv.tm00.bufr_d${OSUFFIX}}
+B1HRS2=${B1HRS2:-${COMIN_OBS}/${OPREFIX}1bhrs2.tm00.bufr_d${OSUFFIX}}
+B1MSU=${B1MSU:-${COMIN_OBS}/${OPREFIX}1bmsu.tm00.bufr_d${OSUFFIX}}
+B1HRS3=${B1HRS3:-${COMIN_OBS}/${OPREFIX}1bhrs3.tm00.bufr_d${OSUFFIX}}
+B1HRS4=${B1HRS4:-${COMIN_OBS}/${OPREFIX}1bhrs4.tm00.bufr_d${OSUFFIX}}
+B1AMUA=${B1AMUA:-${COMIN_OBS}/${OPREFIX}1bamua.tm00.bufr_d${OSUFFIX}}
+B1AMUB=${B1AMUB:-${COMIN_OBS}/${OPREFIX}1bamub.tm00.bufr_d${OSUFFIX}}
+B1MHS=${B1MHS:-${COMIN_OBS}/${OPREFIX}1bmhs.tm00.bufr_d${OSUFFIX}}
+ESHRS3=${ESHRS3:-${COMIN_OBS}/${OPREFIX}eshrs3.tm00.bufr_d${OSUFFIX}}
+ESAMUA=${ESAMUA:-${COMIN_OBS}/${OPREFIX}esamua.tm00.bufr_d${OSUFFIX}}
+ESAMUB=${ESAMUB:-${COMIN_OBS}/${OPREFIX}esamub.tm00.bufr_d${OSUFFIX}}
+ESMHS=${ESMHS:-${COMIN_OBS}/${OPREFIX}esmhs.tm00.bufr_d${OSUFFIX}}
+HRS3DB=${HRS3DB:-${COMIN_OBS}/${OPREFIX}hrs3db.tm00.bufr_d${OSUFFIX}}
+AMUADB=${AMUADB:-${COMIN_OBS}/${OPREFIX}amuadb.tm00.bufr_d${OSUFFIX}}
+AMUBDB=${AMUBDB:-${COMIN_OBS}/${OPREFIX}amubdb.tm00.bufr_d${OSUFFIX}}
+MHSDB=${MHSDB:-${COMIN_OBS}/${OPREFIX}mhsdb.tm00.bufr_d${OSUFFIX}}
+AIRSBF=${AIRSBF:-${COMIN_OBS}/${OPREFIX}airsev.tm00.bufr_d${OSUFFIX}}
+IASIBF=${IASIBF:-${COMIN_OBS}/${OPREFIX}mtiasi.tm00.bufr_d${OSUFFIX}}
+ESIASI=${ESIASI:-${COMIN_OBS}/${OPREFIX}esiasi.tm00.bufr_d${OSUFFIX}}
+IASIDB=${IASIDB:-${COMIN_OBS}/${OPREFIX}iasidb.tm00.bufr_d${OSUFFIX}}
+AMSREBF=${AMSREBF:-${COMIN_OBS}/${OPREFIX}amsre.tm00.bufr_d${OSUFFIX}}
+AMSR2BF=${AMSR2BF:-${COMIN_OBS}/${OPREFIX}amsr2.tm00.bufr_d${OSUFFIX}}
+GMI1CRBF=${GMI1CRBF:-${COMIN_OBS}/${OPREFIX}gmi1cr.tm00.bufr_d${OSUFFIX}}
+SAPHIRBF=${SAPHIRBF:-${COMIN_OBS}/${OPREFIX}saphir.tm00.bufr_d${OSUFFIX}}
+SEVIRIBF=${SEVIRIBF:-${COMIN_OBS}/${OPREFIX}sevcsr.tm00.bufr_d${OSUFFIX}}
+AHIBF=${AHIBF:-${COMIN_OBS}/${OPREFIX}ahicsr.tm00.bufr_d${OSUFFIX}}
+ABIBF=${ABIBF:-${COMIN_OBS}/${OPREFIX}gsrcsr.tm00.bufr_d${OSUFFIX}}
+CRISBF=${CRISBF:-${COMIN_OBS}/${OPREFIX}cris.tm00.bufr_d${OSUFFIX}}
+ESCRIS=${ESCRIS:-${COMIN_OBS}/${OPREFIX}escris.tm00.bufr_d${OSUFFIX}}
+CRISDB=${CRISDB:-${COMIN_OBS}/${OPREFIX}crisdb.tm00.bufr_d${OSUFFIX}}
+CRISFSBF=${CRISFSBF:-${COMIN_OBS}/${OPREFIX}crisf4.tm00.bufr_d${OSUFFIX}}
+ESCRISFS=${ESCRISFS:-${COMIN_OBS}/${OPREFIX}escrsf.tm00.bufr_d${OSUFFIX}}
+CRISFSDB=${CRISFSDB:-${COMIN_OBS}/${OPREFIX}crsfdb.tm00.bufr_d${OSUFFIX}}
+ATMSBF=${ATMSBF:-${COMIN_OBS}/${OPREFIX}atms.tm00.bufr_d${OSUFFIX}}
+ESATMS=${ESATMS:-${COMIN_OBS}/${OPREFIX}esatms.tm00.bufr_d${OSUFFIX}}
+ATMSDB=${ATMSDB:-${COMIN_OBS}/${OPREFIX}atmsdb.tm00.bufr_d${OSUFFIX}}
+ESATMS=${ESATMS:-${COMIN_OBS}/${OPREFIX}esatms.tm00.bufr_d${OSUFFIX}}
+ATMSDB=${ATMSDB:-${COMIN_OBS}/${OPREFIX}atmsdb.tm00.bufr_d${OSUFFIX}}
+SSMITBF=${SSMITBF:-${COMIN_OBS}/${OPREFIX}ssmit.tm00.bufr_d${OSUFFIX}}
+SSMISBF=${SSMISBF:-${COMIN_OBS}/${OPREFIX}ssmisu.tm00.bufr_d${OSUFFIX}}
+SBUVBF=${SBUVBF:-${COMIN_OBS}/${OPREFIX}osbuv8.tm00.bufr_d${OSUFFIX}}
+OMPSNPBF=${OMPSNPBF:-${COMIN_OBS}/${OPREFIX}ompsn8.tm00.bufr_d${OSUFFIX}}
+OMPSTCBF=${OMPSTCBF:-${COMIN_OBS}/${OPREFIX}ompst8.tm00.bufr_d${OSUFFIX}}
+GOMEBF=${GOMEBF:-${COMIN_OBS}/${OPREFIX}gome.tm00.bufr_d${OSUFFIX}}
+OMIBF=${OMIBF:-${COMIN_OBS}/${OPREFIX}omi.tm00.bufr_d${OSUFFIX}}
+MLSBF=${MLSBF:-${COMIN_OBS}/${OPREFIX}mls.tm00.bufr_d${OSUFFIX}}
+OMPSLPBF=${OMPSLPBF:-${COMIN_OBS}/${OPREFIX}ompslp.tm00.bufr_d${OSUFFIX}}
+SMIPCP=${SMIPCP:-${COMIN_OBS}/${OPREFIX}spssmi.tm00.bufr_d${OSUFFIX}}
+TMIPCP=${TMIPCP:-${COMIN_OBS}/${OPREFIX}sptrmm.tm00.bufr_d${OSUFFIX}}
+if [[ ${use_bufr_nr:-no} = "no" ]]; then
+ GPSROBF=${GPSROBF:-${COMIN_OBS}/${OPREFIX}gpsro.tm00.bufr_d${OSUFFIX}}
+else
+ GPSROBF=${GPSROBF:-${COMIN_OBS}/${OPREFIX}gpsro.tm00.bufr_d.nr}
+fi
+TCVITL=${TCVITL:-${COMIN_GFS}/${OPREFIX}syndata.tcvitals.tm00}
+B1AVHAM=${B1AVHAM:-${COMIN_OBS}/${OPREFIX}avcsam.tm00.bufr_d${OSUFFIX}}
+B1AVHPM=${B1AVHPM:-${COMIN_OBS}/${OPREFIX}avcspm.tm00.bufr_d${OSUFFIX}}
+
+# Observational data
+if [[ ${use_bufr_nr:-no} = "no" ]] && [ -s $PREPQC ]; then
+ $ncp -Lp $PREPQC prepbufr
+else
+ touch prepbufr
+fi
+ln -sf $SATWND satwndbufr
+ln -sf $SATWHR satwhrbufr
+ln -sf $GSNDBF1 gsnd1bufr
+ln -sf $B1AMUA amsuabufr
+ln -sf $B1MHS mhsbufr
+ln -sf $ESAMUA amsuabufrears
+ln -sf $SBUVBF sbuvbufr
+ln -sf $OMPSNPBF ompsnpbufr
+ln -sf $OMPSTCBF ompstcbufr
+ln -sf $GOMEBF gomebufr
+ln -sf $OMIBF omibufr
+ln -sf $MLSBF mlsbufr
+ln -sf $AIRSBF airsbufr
+ln -sf $IASIBF iasibufr
+ln -sf $ESIASI iasibufrears
+ln -sf $IASIDB iasibufr_db
+ln -sf $AMSR2BF amsr2bufr
+ln -sf $GMI1CRBF gmibufr
+ln -sf $SAPHIRBF saphirbufr
+ln -sf $SEVIRIBF seviribufr
+ln -sf $CRISBF crisbufr
+ln -sf $ESCRIS crisbufrears
+ln -sf $CRISDB crisbufr_db
+ln -sf $CRISFSBF crisfsbufr
+ln -sf $ESCRISFS crisfsbufrears
+ln -sf $CRISFSDB crisfsbufr_db
+ln -sf $ATMSBF atmsbufr
+ln -sf $ESATMS atmsbufrears
+ln -sf $ATMSDB atmsbufr_db
+ln -sf $SSMISBF ssmisbufr
+ln -sf $GPSROBF gpsrobufr
+ln -sf $TCVITL tcvitl
+ln -sf $B1AVHAM avhambufr
+ln -sf $B1AVHPM avhpmbufr
+
+if [[ ${use_bufr_nr:-no} = "yes" ]]; then
+
+ if [ -s ${PREPQC}.nr ]; then
+ $ncp -L ${PREPQC}.nr prepbufr
+ fi
+ ln -sf ${SAPHIRBF}.nr saphirbufr
+
+fi
+# HAFS specific observations
+INTCOMobs=${WORKhafs}/obs_prep
+# Use updated prepbufr if exists
+if [ -s ${INTCOMobs}/hafs.t${cyc}z.prepbufr ]; then
+ ln -s ${INTCOMobs}/hafs.t${cyc}z.prepbufr prepbufr
+fi
+# cat tempdrop.prepbufr with drifting correction into prepbufr
+if [ -s ${INTCOMobs}/hafs.t${cyc}z.tempdrop.prepbufr ]; then
+ cat ${INTCOMobs}/hafs.t${cyc}z.tempdrop.prepbufr >> prepbufr
+fi
+if [ -s ${INTCOMobs}/hafs.t${cyc}z.tldplr.tm00.bufr_d ]; then
+ ln -s ${INTCOMobs}/hafs.t${cyc}z.tldplr.tm00.bufr_d tldplrbufr
+fi
+if [ -s ${INTCOMobs}/hafs.t${cyc}z.hdob.tm00.bufr_d ]; then
+ ln -s ${INTCOMobs}/hafs.t${cyc}z.hdob.tm00.bufr_d hdobbufr
+fi
+if [ -s ${INTCOMobs}/hafs.t${cyc}z.nexrad.tm00.bufr_d ]; then
+ ln -s ${INTCOMobs}/hafs.t${cyc}z.nexrad.tm00.bufr_d l2rwbufr
+fi
+
+
+#
+#-----------------------------------------------------------------------
+#
+# Create links to fix files in the FIXgsi directory.
+#
+#-----------------------------------------------------------------------
+
+ln -sf ${inputdata}/berror_stats .
+ln -sf ${inputdata}/satinfo .
+ln -sf ${inputdata}/atms_beamwidth.txt .
+ln -sf ${inputdata}/anavinfo .
+ln -sf ${inputdata}/convinfo .
+ln -sf ${inputdata}/ozinfo .
+ln -sf ${inputdata}/pcpinfo .
+ln -sf ${inputdata}/scaninfo .
+ln -sf ${inputdata}/errtable .
+ln -sf ${inputdata}/prepobs_prep.bufrtable .
+ln -sf ${inputdata}/bftab_sstphr .
+
+#-----------------------------------------------------------------------
+#
+# CRTM Spectral and Transmittance coefficients
+#
+#-----------------------------------------------------------------------
+emiscoef_IRwater=${fixcrtm}/Nalli.IRwater.EmisCoeff.bin
+emiscoef_IRice=${fixcrtm}/NPOESS.IRice.EmisCoeff.bin
+emiscoef_IRland=${fixcrtm}/NPOESS.IRland.EmisCoeff.bin
+emiscoef_IRsnow=${fixcrtm}/NPOESS.IRsnow.EmisCoeff.bin
+emiscoef_VISice=${fixcrtm}/NPOESS.VISice.EmisCoeff.bin
+emiscoef_VISland=${fixcrtm}/NPOESS.VISland.EmisCoeff.bin
+emiscoef_VISsnow=${fixcrtm}/NPOESS.VISsnow.EmisCoeff.bin
+emiscoef_VISwater=${fixcrtm}/NPOESS.VISwater.EmisCoeff.bin
+emiscoef_MWwater=${fixcrtm}/FASTEM6.MWwater.EmisCoeff.bin
+aercoef=${fixcrtm}/AerosolCoeff.bin
+cldcoef=${fixcrtm}/CloudCoeff.bin
+
+ln -sf ${emiscoef_IRwater} Nalli.IRwater.EmisCoeff.bin
+ln -sf $emiscoef_IRice ./NPOESS.IRice.EmisCoeff.bin
+ln -sf $emiscoef_IRsnow ./NPOESS.IRsnow.EmisCoeff.bin
+ln -sf $emiscoef_IRland ./NPOESS.IRland.EmisCoeff.bin
+ln -sf $emiscoef_VISice ./NPOESS.VISice.EmisCoeff.bin
+ln -sf $emiscoef_VISland ./NPOESS.VISland.EmisCoeff.bin
+ln -sf $emiscoef_VISsnow ./NPOESS.VISsnow.EmisCoeff.bin
+ln -sf $emiscoef_VISwater ./NPOESS.VISwater.EmisCoeff.bin
+ln -sf $emiscoef_MWwater ./FASTEM6.MWwater.EmisCoeff.bin
+ln -sf $aercoef ./AerosolCoeff.bin
+ln -sf $cldcoef ./CloudCoeff.bin
+
+
+# Copy CRTM coefficient files based on entries in satinfo file
+for file in $(awk '{if($1!~"!"){print $1}}' ./satinfo | sort | uniq) ;do
+ ln -sf ${fixcrtm}/${file}.SpcCoeff.bin ./
+ ln -sf ${fixcrtm}/${file}.TauCoeff.bin ./
+done
+
+# Read from previous cycles for satbias predictors (no online satbias)
+PASSIVE_BC=.false.
+UPD_PRED=0
+ln -sf ${COMINgdas}/gdas.t${hhprior}z.abias satbias_in
+ln -sf ${COMINgdas}/gdas.t${hhprior}z.abias_pc satbias_pc
+
+#-----------------------------------------------------------------------
+#
+# Build the GSI namelist on-the-fly
+#
+#-----------------------------------------------------------------------
+#
+
+. $scripts/regression_nl_update.sh
+
+SETUP="$SETUP_update"
+GRIDOPTS="$GRIDOPTS_update"
+BKGVERR="$BKGVERR_update"
+ANBKGERR="$ANBKERR_update"
+JCOPTS="$JCOPTS_update"
+STRONGOPTS="$STRONGOPTS_update"
+OBSQC="$OBSQC_update"
+OBSINPUT="$OBSINPUT_update"
+SUPERRAD="$SUPERRAD_update"
+HYBRID_ENSEMBLE='ensemble_path="",'
+SINGLEOB="$SINGLEOB_update"
+
+if [ "$debug" = ".false." ]; then
+ . $scripts/regression_namelists.sh hafs_envar
+else
+ . $scripts/regression_namelists_db.sh hafs_envar
+fi
+
+cat << EOF > gsiparm.anl
+
+$gsi_namelist
+
+EOF
+
+# Copy executable and fixed files to $tmpdir
+if [[ $exp == *"updat"* ]]; then
+ $ncp $gsiexec_updat ./gsi.x
+elif [[ $exp == *"contrl"* ]]; then
+ $ncp $gsiexec_contrl ./gsi.x
+fi
+
+# Run GSI
+cd $tmpdir
+echo "run gsi now"
+eval "$APRUN $tmpdir/gsi.x > stdout 2>&1"
+rc=$?
+exit $rc
+
+
+
diff --git a/regression/hafs_4denvar_glbens.sh b/regression/hafs_4denvar_glbens.sh
new file mode 100755
index 0000000000..ddbd53dcf9
--- /dev/null
+++ b/regression/hafs_4denvar_glbens.sh
@@ -0,0 +1,451 @@
+set -x
+# Set variables used in script
+# CLEAN up $tmpdir when finished (YES=remove, NO=leave alone)
+# ncp is cp replacement, currently keep as /bin/cp
+
+UNCOMPRESS=gunzip
+CLEAN=NO
+ncp=/bin/cp
+nln="/bin/ln -sf"
+
+# HAFS test cases set up
+RUN_FGAT=YES # use FGAT or not
+RUN_ENSDA=NO
+l4densvar=.true.
+nhr_obsbin=3
+l_both_fv3sar_gfs_ens=.false.
+n_ens_gfs=5
+n_ens_fv3sar=5
+
+#
+# Set experiment name
+#
+exp=$jobname
+
+#-----------------------------------------------------------------------
+#
+# Extract from ADATE the starting year, month, day, and hour of the
+# forecast. These are needed below for various operations.
+#
+#-----------------------------------------------------------------------
+#
+adate=${hafs_envar_adate}
+YYYYMMDDHH=$(date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2}")
+JJJ=$(date +%j -d "${adate:0:8} ${adate:8:2}")
+
+YYYY=${YYYYMMDDHH:0:4}
+MM=${YYYYMMDDHH:4:2}
+DD=${YYYYMMDDHH:6:2}
+HH=${YYYYMMDDHH:8:2}
+YYYYMMDD=${YYYYMMDDHH:0:8}
+PDY=${YYYYMMDD}
+cyc=${HH}
+# prior date and hour
+adateprior=`date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2} - 6 hours"`
+
+ymdprior=$(echo ${adateprior} | cut -c1-8)
+hhprior=$(echo ${adateprior} | cut -c9-10)
+
+CDATEtm03=`date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2} - 3 hours"`
+ymdtm03=$(echo ${CDATEtm03} | cut -c1-8)
+hhtm03=$(echo ${CDATEtm03} | cut -c9-10)
+
+CDATEtp03=`date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2} + 3 hours"`
+ymdtp03=$(echo ${CDATEtp03} | cut -c1-8)
+hhtp03=$(echo ${CDATEtp03} | cut -c9-10)
+
+#
+#-----------------------------------------------------------------------
+#
+# go to working directory and save directory.
+# define fix and background path
+#
+#-----------------------------------------------------------------------
+# Set runtime and save directories
+tmpdir=$tmpdir/tmpreg_hafs_4denvar_glbens/${exp}
+savdir=$savdir/outreg_hafs_4denvar_glbens/${exp}
+
+# Set up $tmpdir
+rm -rf $tmpdir
+mkdir -p $tmpdir
+chgrp rstprod $tmpdir
+chmod 750 $tmpdir
+cd $tmpdir
+
+bkpath=${hafs_envar_ges}
+fixcrtm=${fixcrtm:-$CRTM_FIX}
+
+################################################################
+##### input data and fix directory #######################
+inputdata=${hafs_envar_ges}
+COMINgdas=${hafs_envar_ens}
+COMINobs=${hafs_envar_obs}
+COMINgfs=${hafs_envar_obs}
+WORKhafs=${hafs_envar_obs}
+##########################################################
+
+# use FGAT or not
+if [ ${RUN_FGAT} = "YES" ]; then
+ ln -sf ${inputdata}/coupler.res_03 .
+ ln -sf ${inputdata}/fv3_akbk_03 .
+ ln -sf ${inputdata}/fv3_sfcdata_03 .
+ ln -sf ${inputdata}/fv3_srfwnd_03 .
+ ln -sf ${inputdata}/fv3_dynvars_03 .
+ ln -sf ${inputdata}/fv3_tracer_03 .
+
+ ln -sf ${inputdata}/coupler.res_09 .
+ ln -sf ${inputdata}/fv3_akbk_09 .
+ ln -sf ${inputdata}/fv3_sfcdata_09 .
+ ln -sf ${inputdata}/fv3_srfwnd_09 .
+ ln -sf ${inputdata}/fv3_dynvars_09 .
+ ln -sf ${inputdata}/fv3_tracer_09 .
+fi
+
+# copy background and grib configuration files
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.coupler.res ./coupler.res
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.fv_core.res.nc ./fv3_akbk
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.sfc_data.nc ./fv3_sfcdata
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.fv_srf_wnd.res.tile1.nc ./fv3_srfwnd
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.fv_core.res.tile1.nc ./fv3_dynvars
+cp ${bkpath}/${YYYYMMDD}.${HH}0000.fv_tracer.res.tile1.nc ./fv3_tracer
+
+cp ${bkpath}/oro_data.nc ./fv3_oro_data
+cp ${bkpath}/atmos_static.nc ./fv3_atmos_static
+cp ${bkpath}/grid_spec.nc ./fv3_grid_spec
+
+# create ensemble member file list
+if [ ${RUN_ENSDA} != "YES" ] || [ $l_both_fv3sar_gfs_ens = .true. ]; then
+# Link gdas ensemble members
+ mkdir -p ensemble_data
+ GSUFFIX=${GSUFFIX:-.nc}
+ if [ ${l4densvar:-.false.} = ".true." ]; then
+ fhrs="03 06 09"
+ else
+ fhrs="06"
+ fi
+ for fhh in $fhrs; do
+ rm -f filelist${fhh}
+ for mem in $(seq -f '%03g' 1 ${n_ens_gfs}); do
+ if [ -s ${COMINgdas}/enkfgdas.${ymdprior}/${hhprior}/atmos/mem${mem}/gdas.t${hhprior}z.atmf0${fhh}s${GSUFFIX:-.nc} ]; then
+ ${nln} ${COMINgdas}/enkfgdas.${ymdprior}/${hhprior}/atmos/mem${mem}/gdas.t${hhprior}z.atmf0${fhh}s${GSUFFIX:-.nc} ./ensemble_data/enkfgdas.${ymdprior}${hhprior}.atmf0${fhh}_ens_${mem}
+ elif [ -s ${COMINgdas}/enkfgdas.${ymdprior}/${hhprior}/atmos/mem${mem}/gdas.t${hhprior}z.atmf0${fhh}${GSUFFIX:-.nc} ]; then
+ ${nln} ${COMINgdas}/enkfgdas.${ymdprior}/${hhprior}/atmos/mem${mem}/gdas.t${hhprior}z.atmf0${fhh}${GSUFFIX:-.nc} ./ensemble_data/enkfgdas.${ymdprior}${hhprior}.atmf0${fhh}_ens_${mem}
+ fi
+ echo "./ensemble_data/enkfgdas.${ymdprior}${hhprior}.atmf0${fhh}_ens_${mem}" >> filelist${fhh}
+ done
+ done
+fi
+
+if [ ${RUN_ENSDA} = "YES" ]; then
+ for mem in $(seq -f '%03g' 1 ${n_ens_fv3sar})
+ do
+ RESTARTens=${inputdata}
+ fhh="06"
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-coupler.res .
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-fv3_akbk .
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-fv3_sfcdata .
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-fv3_srfwnd .
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-fv3_dynvars .
+ ln -sf ${inputdata}/fv3SAR${fhh}_ens_mem${mem}-fv3_tracer .
+ if [ ! -s ./fv3_ens_grid_spec ]; then
+ ln -sf ${RESTARTens}/grid_spec.nc ./fv3_ens_grid_spec
+ fi
+ if [ ${l4densvar:-.false.} = ".true." ]; then
+ export ENS_NSTARTHR=3
+ fhh="03"
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-coupler.res .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_akbk .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_sfcdata .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_srfwnd .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_dynvars .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_tracer .
+ fhh="09"
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-coupler.res .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_akbk .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_sfcdata .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_srfwnd .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_dynvars .
+ ${nln} ${RESTARTens}/fv3SAR${fhh}_ens_mem${mem}-fv3_tracer .
+ fi
+ done
+fi
+if [ ${RUN_ENSDA} != "YES" ]; then
+ export N_ENS=${n_ens_gfs}
+ export BETA_S0=${BETA_S0:-0.2}
+ export GRID_RATIO_ENS=1
+ export REGIONAL_ENSEMBLE_OPTION=1
+elif [ ${RUN_ENSDA} = "YES" ]; then
+ if [ $l_both_fv3sar_gfs_ens = .false. ]; then
+ export N_ENS=${n_ens_fv3sar}
+ export BETA_S0=${BETA_S0:-0.0}
+ export GRID_RATIO_ENS=2
+ export grid_ratio_fv3_regional=2
+ export REGIONAL_ENSEMBLE_OPTION=5
+ elif [ $l_both_fv3sar_gfs_ens = .true. ]; then
+ export N_ENS=$((${n_ens_gfs} + ${n_ens_fv3sar}))
+ export BETA_S0=${BETA_S0:-0.0}
+ export GRID_RATIO_ENS=2
+ export grid_ratio_fv3_regional=2
+ export REGIONAL_ENSEMBLE_OPTION=5
+ fi
+fi
+
+#-----------------------------------------------------------------------
+#
+# link observation files
+# copy observation files to working directory
+#
+#-----------------------------------------------------------------------
+
+# Link GFS/GDAS input and observation files
+COMIN_OBS=${COMIN_OBS:-${COMINobs}}
+COMIN_GFS=${COMIN_GFS:-${COMINgfs}}
+
+OPREFIX=${OPREFIX:-"gfs.t${cyc}z."}
+OSUFFIX=${OSUFFIX:-""}
+PREPQC=${PREPQC:-${COMIN_OBS}/${OPREFIX}prepbufr${OSUFFIX}}
+PREPQCPF=${PREPQCPF:-${COMIN_OBS}/${OPREFIX}prepbufr.acft_profiles${OSUFFIX}}
+NSSTBF=${NSSTBF:-${COMIN_OBS}/${OPREFIX}nsstbufr${OSUFFIX}}
+SATWND=${SATWND:-${COMIN_OBS}/${OPREFIX}satwnd.tm00.bufr_d${OSUFFIX}}
+SATWHR=${SATWHR:-${COMIN_OBS}/${OPREFIX}satwhr.tm00.bufr_d${OSUFFIX}}
+OSCATBF=${OSCATBF:-${COMIN_OBS}/${OPREFIX}oscatw.tm00.bufr_d${OSUFFIX}}
+RAPIDSCATBF=${RAPIDSCATBF:-${COMIN_OBS}/${OPREFIX}rapidscatw.tm00.bufr_d${OSUFFIX}}
+GSNDBF=${GSNDBF:-${COMIN_OBS}/${OPREFIX}goesnd.tm00.bufr_d${OSUFFIX}}
+GSNDBF1=${GSNDBF1:-${COMIN_OBS}/${OPREFIX}goesfv.tm00.bufr_d${OSUFFIX}}
+B1HRS2=${B1HRS2:-${COMIN_OBS}/${OPREFIX}1bhrs2.tm00.bufr_d${OSUFFIX}}
+B1MSU=${B1MSU:-${COMIN_OBS}/${OPREFIX}1bmsu.tm00.bufr_d${OSUFFIX}}
+B1HRS3=${B1HRS3:-${COMIN_OBS}/${OPREFIX}1bhrs3.tm00.bufr_d${OSUFFIX}}
+B1HRS4=${B1HRS4:-${COMIN_OBS}/${OPREFIX}1bhrs4.tm00.bufr_d${OSUFFIX}}
+B1AMUA=${B1AMUA:-${COMIN_OBS}/${OPREFIX}1bamua.tm00.bufr_d${OSUFFIX}}
+B1AMUB=${B1AMUB:-${COMIN_OBS}/${OPREFIX}1bamub.tm00.bufr_d${OSUFFIX}}
+B1MHS=${B1MHS:-${COMIN_OBS}/${OPREFIX}1bmhs.tm00.bufr_d${OSUFFIX}}
+ESHRS3=${ESHRS3:-${COMIN_OBS}/${OPREFIX}eshrs3.tm00.bufr_d${OSUFFIX}}
+ESAMUA=${ESAMUA:-${COMIN_OBS}/${OPREFIX}esamua.tm00.bufr_d${OSUFFIX}}
+ESAMUB=${ESAMUB:-${COMIN_OBS}/${OPREFIX}esamub.tm00.bufr_d${OSUFFIX}}
+ESMHS=${ESMHS:-${COMIN_OBS}/${OPREFIX}esmhs.tm00.bufr_d${OSUFFIX}}
+HRS3DB=${HRS3DB:-${COMIN_OBS}/${OPREFIX}hrs3db.tm00.bufr_d${OSUFFIX}}
+AMUADB=${AMUADB:-${COMIN_OBS}/${OPREFIX}amuadb.tm00.bufr_d${OSUFFIX}}
+AMUBDB=${AMUBDB:-${COMIN_OBS}/${OPREFIX}amubdb.tm00.bufr_d${OSUFFIX}}
+MHSDB=${MHSDB:-${COMIN_OBS}/${OPREFIX}mhsdb.tm00.bufr_d${OSUFFIX}}
+AIRSBF=${AIRSBF:-${COMIN_OBS}/${OPREFIX}airsev.tm00.bufr_d${OSUFFIX}}
+IASIBF=${IASIBF:-${COMIN_OBS}/${OPREFIX}mtiasi.tm00.bufr_d${OSUFFIX}}
+ESIASI=${ESIASI:-${COMIN_OBS}/${OPREFIX}esiasi.tm00.bufr_d${OSUFFIX}}
+IASIDB=${IASIDB:-${COMIN_OBS}/${OPREFIX}iasidb.tm00.bufr_d${OSUFFIX}}
+AMSREBF=${AMSREBF:-${COMIN_OBS}/${OPREFIX}amsre.tm00.bufr_d${OSUFFIX}}
+AMSR2BF=${AMSR2BF:-${COMIN_OBS}/${OPREFIX}amsr2.tm00.bufr_d${OSUFFIX}}
+GMI1CRBF=${GMI1CRBF:-${COMIN_OBS}/${OPREFIX}gmi1cr.tm00.bufr_d${OSUFFIX}}
+SAPHIRBF=${SAPHIRBF:-${COMIN_OBS}/${OPREFIX}saphir.tm00.bufr_d${OSUFFIX}}
+SEVIRIBF=${SEVIRIBF:-${COMIN_OBS}/${OPREFIX}sevcsr.tm00.bufr_d${OSUFFIX}}
+AHIBF=${AHIBF:-${COMIN_OBS}/${OPREFIX}ahicsr.tm00.bufr_d${OSUFFIX}}
+ABIBF=${ABIBF:-${COMIN_OBS}/${OPREFIX}gsrcsr.tm00.bufr_d${OSUFFIX}}
+CRISBF=${CRISBF:-${COMIN_OBS}/${OPREFIX}cris.tm00.bufr_d${OSUFFIX}}
+ESCRIS=${ESCRIS:-${COMIN_OBS}/${OPREFIX}escris.tm00.bufr_d${OSUFFIX}}
+CRISDB=${CRISDB:-${COMIN_OBS}/${OPREFIX}crisdb.tm00.bufr_d${OSUFFIX}}
+CRISFSBF=${CRISFSBF:-${COMIN_OBS}/${OPREFIX}crisf4.tm00.bufr_d${OSUFFIX}}
+ESCRISFS=${ESCRISFS:-${COMIN_OBS}/${OPREFIX}escrsf.tm00.bufr_d${OSUFFIX}}
+CRISFSDB=${CRISFSDB:-${COMIN_OBS}/${OPREFIX}crsfdb.tm00.bufr_d${OSUFFIX}}
+ATMSBF=${ATMSBF:-${COMIN_OBS}/${OPREFIX}atms.tm00.bufr_d${OSUFFIX}}
+ESATMS=${ESATMS:-${COMIN_OBS}/${OPREFIX}esatms.tm00.bufr_d${OSUFFIX}}
+ATMSDB=${ATMSDB:-${COMIN_OBS}/${OPREFIX}atmsdb.tm00.bufr_d${OSUFFIX}}
+ESATMS=${ESATMS:-${COMIN_OBS}/${OPREFIX}esatms.tm00.bufr_d${OSUFFIX}}
+ATMSDB=${ATMSDB:-${COMIN_OBS}/${OPREFIX}atmsdb.tm00.bufr_d${OSUFFIX}}
+SSMITBF=${SSMITBF:-${COMIN_OBS}/${OPREFIX}ssmit.tm00.bufr_d${OSUFFIX}}
+SSMISBF=${SSMISBF:-${COMIN_OBS}/${OPREFIX}ssmisu.tm00.bufr_d${OSUFFIX}}
+SBUVBF=${SBUVBF:-${COMIN_OBS}/${OPREFIX}osbuv8.tm00.bufr_d${OSUFFIX}}
+OMPSNPBF=${OMPSNPBF:-${COMIN_OBS}/${OPREFIX}ompsn8.tm00.bufr_d${OSUFFIX}}
+OMPSTCBF=${OMPSTCBF:-${COMIN_OBS}/${OPREFIX}ompst8.tm00.bufr_d${OSUFFIX}}
+GOMEBF=${GOMEBF:-${COMIN_OBS}/${OPREFIX}gome.tm00.bufr_d${OSUFFIX}}
+OMIBF=${OMIBF:-${COMIN_OBS}/${OPREFIX}omi.tm00.bufr_d${OSUFFIX}}
+MLSBF=${MLSBF:-${COMIN_OBS}/${OPREFIX}mls.tm00.bufr_d${OSUFFIX}}
+OMPSLPBF=${OMPSLPBF:-${COMIN_OBS}/${OPREFIX}ompslp.tm00.bufr_d${OSUFFIX}}
+SMIPCP=${SMIPCP:-${COMIN_OBS}/${OPREFIX}spssmi.tm00.bufr_d${OSUFFIX}}
+TMIPCP=${TMIPCP:-${COMIN_OBS}/${OPREFIX}sptrmm.tm00.bufr_d${OSUFFIX}}
+if [[ ${use_bufr_nr:-no} = "no" ]]; then
+ GPSROBF=${GPSROBF:-${COMIN_OBS}/${OPREFIX}gpsro.tm00.bufr_d${OSUFFIX}}
+else
+ GPSROBF=${GPSROBF:-${COMIN_OBS}/${OPREFIX}gpsro.tm00.bufr_d.nr}
+fi
+TCVITL=${TCVITL:-${COMIN_GFS}/${OPREFIX}syndata.tcvitals.tm00}
+B1AVHAM=${B1AVHAM:-${COMIN_OBS}/${OPREFIX}avcsam.tm00.bufr_d${OSUFFIX}}
+B1AVHPM=${B1AVHPM:-${COMIN_OBS}/${OPREFIX}avcspm.tm00.bufr_d${OSUFFIX}}
+
+# Observational data
+if [[ ${use_bufr_nr:-no} = "no" ]] && [ -s $PREPQC ]; then
+ $ncp -Lp $PREPQC prepbufr
+else
+ touch prepbufr
+fi
+ln -sf $SATWND satwndbufr
+ln -sf $SATWHR satwhrbufr
+ln -sf $GSNDBF1 gsnd1bufr
+ln -sf $B1AMUA amsuabufr
+ln -sf $B1MHS mhsbufr
+ln -sf $ESAMUA amsuabufrears
+ln -sf $SBUVBF sbuvbufr
+ln -sf $OMPSNPBF ompsnpbufr
+ln -sf $OMPSTCBF ompstcbufr
+ln -sf $GOMEBF gomebufr
+ln -sf $OMIBF omibufr
+ln -sf $MLSBF mlsbufr
+ln -sf $AIRSBF airsbufr
+ln -sf $IASIBF iasibufr
+ln -sf $ESIASI iasibufrears
+ln -sf $IASIDB iasibufr_db
+ln -sf $AMSR2BF amsr2bufr
+ln -sf $GMI1CRBF gmibufr
+ln -sf $SAPHIRBF saphirbufr
+ln -sf $SEVIRIBF seviribufr
+ln -sf $CRISBF crisbufr
+ln -sf $ESCRIS crisbufrears
+ln -sf $CRISDB crisbufr_db
+ln -sf $CRISFSBF crisfsbufr
+ln -sf $ESCRISFS crisfsbufrears
+ln -sf $CRISFSDB crisfsbufr_db
+ln -sf $ATMSBF atmsbufr
+ln -sf $ESATMS atmsbufrears
+ln -sf $ATMSDB atmsbufr_db
+ln -sf $SSMISBF ssmisbufr
+ln -sf $GPSROBF gpsrobufr
+ln -sf $TCVITL tcvitl
+ln -sf $B1AVHAM avhambufr
+ln -sf $B1AVHPM avhpmbufr
+
+if [[ ${use_bufr_nr:-no} = "yes" ]]; then
+
+ if [ -s ${PREPQC}.nr ]; then
+ $ncp -L ${PREPQC}.nr prepbufr
+ fi
+ ln -sf ${SAPHIRBF}.nr saphirbufr
+
+fi
+# HAFS specific observations
+INTCOMobs=${WORKhafs}/obs_prep
+# Use updated prepbufr if exists
+if [ -s ${INTCOMobs}/hafs.t${cyc}z.prepbufr ]; then
+ ln -s ${INTCOMobs}/hafs.t${cyc}z.prepbufr prepbufr
+fi
+# cat tempdrop.prepbufr with drifting correction into prepbufr
+if [ -s ${INTCOMobs}/hafs.t${cyc}z.tempdrop.prepbufr ]; then
+ cat ${INTCOMobs}/hafs.t${cyc}z.tempdrop.prepbufr >> prepbufr
+fi
+if [ -s ${INTCOMobs}/hafs.t${cyc}z.tldplr.tm00.bufr_d ]; then
+ ln -s ${INTCOMobs}/hafs.t${cyc}z.tldplr.tm00.bufr_d tldplrbufr
+fi
+if [ -s ${INTCOMobs}/hafs.t${cyc}z.hdob.tm00.bufr_d ]; then
+ ln -s ${INTCOMobs}/hafs.t${cyc}z.hdob.tm00.bufr_d hdobbufr
+fi
+if [ -s ${INTCOMobs}/hafs.t${cyc}z.nexrad.tm00.bufr_d ]; then
+ ln -s ${INTCOMobs}/hafs.t${cyc}z.nexrad.tm00.bufr_d l2rwbufr
+fi
+
+
+#
+#-----------------------------------------------------------------------
+#
+# Create links to fix files in the FIXgsi directory.
+#
+#-----------------------------------------------------------------------
+
+ln -sf ${inputdata}/berror_stats .
+ln -sf ${inputdata}/satinfo .
+ln -sf ${inputdata}/atms_beamwidth.txt .
+ln -sf ${inputdata}/anavinfo .
+ln -sf ${inputdata}/convinfo .
+ln -sf ${inputdata}/ozinfo .
+ln -sf ${inputdata}/pcpinfo .
+ln -sf ${inputdata}/scaninfo .
+ln -sf ${inputdata}/errtable .
+ln -sf ${inputdata}/prepobs_prep.bufrtable .
+ln -sf ${inputdata}/bftab_sstphr .
+
+#-----------------------------------------------------------------------
+#
+# CRTM Spectral and Transmittance coefficients
+#
+#-----------------------------------------------------------------------
+emiscoef_IRwater=${fixcrtm}/Nalli.IRwater.EmisCoeff.bin
+emiscoef_IRice=${fixcrtm}/NPOESS.IRice.EmisCoeff.bin
+emiscoef_IRland=${fixcrtm}/NPOESS.IRland.EmisCoeff.bin
+emiscoef_IRsnow=${fixcrtm}/NPOESS.IRsnow.EmisCoeff.bin
+emiscoef_VISice=${fixcrtm}/NPOESS.VISice.EmisCoeff.bin
+emiscoef_VISland=${fixcrtm}/NPOESS.VISland.EmisCoeff.bin
+emiscoef_VISsnow=${fixcrtm}/NPOESS.VISsnow.EmisCoeff.bin
+emiscoef_VISwater=${fixcrtm}/NPOESS.VISwater.EmisCoeff.bin
+emiscoef_MWwater=${fixcrtm}/FASTEM6.MWwater.EmisCoeff.bin
+aercoef=${fixcrtm}/AerosolCoeff.bin
+cldcoef=${fixcrtm}/CloudCoeff.bin
+
+ln -sf ${emiscoef_IRwater} Nalli.IRwater.EmisCoeff.bin
+ln -sf $emiscoef_IRice ./NPOESS.IRice.EmisCoeff.bin
+ln -sf $emiscoef_IRsnow ./NPOESS.IRsnow.EmisCoeff.bin
+ln -sf $emiscoef_IRland ./NPOESS.IRland.EmisCoeff.bin
+ln -sf $emiscoef_VISice ./NPOESS.VISice.EmisCoeff.bin
+ln -sf $emiscoef_VISland ./NPOESS.VISland.EmisCoeff.bin
+ln -sf $emiscoef_VISsnow ./NPOESS.VISsnow.EmisCoeff.bin
+ln -sf $emiscoef_VISwater ./NPOESS.VISwater.EmisCoeff.bin
+ln -sf $emiscoef_MWwater ./FASTEM6.MWwater.EmisCoeff.bin
+ln -sf $aercoef ./AerosolCoeff.bin
+ln -sf $cldcoef ./CloudCoeff.bin
+
+
+# Copy CRTM coefficient files based on entries in satinfo file
+for file in $(awk '{if($1!~"!"){print $1}}' ./satinfo | sort | uniq) ;do
+ ln -sf ${fixcrtm}/${file}.SpcCoeff.bin ./
+ ln -sf ${fixcrtm}/${file}.TauCoeff.bin ./
+done
+
+# Read from previous cycles for satbias predictors (no online satbias)
+PASSIVE_BC=.false.
+UPD_PRED=0
+ln -sf ${COMINgdas}/gdas.t${hhprior}z.abias satbias_in
+ln -sf ${COMINgdas}/gdas.t${hhprior}z.abias_pc satbias_pc
+
+#-----------------------------------------------------------------------
+#
+# Build the GSI namelist on-the-fly
+#
+#-----------------------------------------------------------------------
+#
+
+. $scripts/regression_nl_update.sh
+
+SETUP="$SETUP_update"
+GRIDOPTS="$GRIDOPTS_update"
+BKGVERR="$BKGVERR_update"
+ANBKGERR="$ANBKERR_update"
+JCOPTS="$JCOPTS_update"
+STRONGOPTS="$STRONGOPTS_update"
+OBSQC="$OBSQC_update"
+OBSINPUT="$OBSINPUT_update"
+SUPERRAD="$SUPERRAD_update"
+HYBRID_ENSEMBLE='ensemble_path="",'
+SINGLEOB="$SINGLEOB_update"
+
+if [ "$debug" = ".false." ]; then
+ . $scripts/regression_namelists.sh hafs_envar
+else
+ . $scripts/regression_namelists_db.sh hafs_envar
+fi
+
+cat << EOF > gsiparm.anl
+
+$gsi_namelist
+
+EOF
+
+# Copy executable and fixed files to $tmpdir
+if [[ $exp == *"updat"* ]]; then
+ $ncp $gsiexec_updat ./gsi.x
+elif [[ $exp == *"contrl"* ]]; then
+ $ncp $gsiexec_contrl ./gsi.x
+fi
+
+# Run GSI
+cd $tmpdir
+echo "run gsi now"
+eval "$APRUN $tmpdir/gsi.x > stdout 2>&1"
+rc=$?
+exit $rc
+
+
+
diff --git a/regression/hwrf_nmm_d2.sh b/regression/hwrf_nmm_d2.sh
deleted file mode 100755
index 2b4d2e1bfe..0000000000
--- a/regression/hwrf_nmm_d2.sh
+++ /dev/null
@@ -1,339 +0,0 @@
-
-set -x
-
-# Set analysis date
-adate=$hwrf_nmm_adate
-
-io_format=netcdf
-
-if [[ "$io_format" = "binary" ]]; then
- NETCDF=.false.
- FORMAT=binary
-elif [[ "$io_format" = "netcdf" ]]; then
- NETCDF=.true.
- FORMAT=netcdf
-else
- echo "***ERRROR*** INVALID io_format = $io_format"
- exit
-fi
-
-# Set experiment name and analysis date
-
-exp=$jobname
-
-# Set path/file for gsi executable
-#gsiexec=$gsiexec
-
-# Set the JCAP resolution which you want.
-# All resolutions use LEVS=64
-#export JCAP=62
-export LEVS=60
-export JCAP_B=$JCAP
-export DELTIM=1200
-
-# Set runtime and save directories
-tmpdir=$tmpdir/tmpreg_hwrf_nmm_d2/${exp}
-savdir=$savdir/outreg_hwrf_nmm_d2/${exp}
-
-# Specify GSI fixed field and data directories.
-fixcrtm=${fixcrtm:-$CRTM_FIX}
-
-#datobs=$datobs
-
-# Set variables used in script
-# CLEAN up $tmpdir when finished (YES=remove, NO=leave alone)
-# ncp is cp replacement, currently keep as /bin/cp
-
-CLEAN=NO
-ncp=/bin/cp
-lnsf='ln -sf'
-
-NX2=166
-NY2=336
-export NLAT=$(( NY2 - 1 ))
-export NLON=$(( NX2 - 1 ))
-
-# Given the analysis date, compute the date from which the
-# first guess comes. Extract cycle and set prefix and suffix
-# for guess and observation data files
-gdate=`date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2} - 6 hours"`
-hha=`echo $adate | cut -c9-10`
-hhg=`echo $gdate | cut -c9-10`
-prefixa=gfs.t${hha}z
-prefixo=gdas1.t${hha}z
-suffix=tm00.bufr_d
-
-
-# Set up $tmpdir
-rm -rf $tmpdir
-mkdir -p $tmpdir
-cd $tmpdir
-rm -rf core*
-
-# Make gsi namelist
-
-. $scripts/regression_nl_update.sh
-
-GRIDOPTS="$GRIDOPTS_update"
-BKGVERR="$BKGVERR_update"
-ANBKGERR="$ANBKERR_update"
-JCOPTS="$JCOPTS_update"
-STRONGOPTS="$STRONGOPTS_update"
-OBSQC="$OBSQC_update"
-OBSINPUT="$OBSINPUT_update"
-SUPERRAD="$SUPERRAD_update"
-SINGLEOB="$SINGLEOB_update"
-
-# parameters for radiance data assimilation
-export SETUP="newpc4pred=.true., adp_anglebc=.true., angord=4, \
- passive_bc=.false., use_edges=.false., emiss_bc=.true., \
- diag_precon=.true., step_start=1.e-3, upd_pred(1)=0, \
- upd_pred(2)=0,upd_pred(3)=0,upd_pred(4)=0, \
- upd_pred(5)=0,upd_pred(6)=0,upd_pred(7)=0, \
- upd_pred(8)=0,upd_pred(9)=0,upd_pred(10)=0, \
- upd_pred(11)=0,upd_pred(12)=0,"
-
-export USE_GFS_STRATOSPHERE=".true."
-export USE_GFS_OZONE=".true."
-export REGIONAL_OZONE=".false."
-
-if [ "$debug" = ".false." ]; then
- . $scripts/regression_namelists.sh hwrf_nmm_d2
-else
- . $scripts/regression_namelists_db.sh hwrf_nmm_d2
-fi
-
-cat << EOF > gsiparm.anl
-
-$gsi_namelist
-
-EOF
-
-# Set fixed files
-# berror = forecast model background error statistics
-# specoef = CRTM spectral coefficients
-# trncoef = CRTM transmittance coefficients
-# emiscoef = CRTM coefficients for IR sea surface emissivity model
-# aerocoef = CRTM coefficients for aerosol effects
-# cldcoef = CRTM coefficients for cloud effects
-# satinfo = text file with information about assimilation of brightness temperatures
-# cloudyinfo = text file with information about assimilation of cloudy radiance
-# pcpinfo = text file with information about assimilation of prepcipitation rates
-# ozinfo = text file with information about assimilation of ozone data
-# errtable = text file with obs error for conventional data (optional)
-# convinfo = text file with information about assimilation of conventional data
-# bufrtable= text file ONLY needed for single obs test (oneobstest=.true.)
-# bftab_sst= bufr table for sst ONLY needed for sst retrieval (retrieval=.true.)
-
-anavinfo=$fixgsi/anavinfo_hwrf_L75
-berror=$fixgsi/$endianness/nam_glb_berror.f77.gcv
-emiscoef_IRwater=$fixcrtm/Nalli.IRwater.EmisCoeff.bin
-emiscoef_IRice=$fixcrtm/NPOESS.IRice.EmisCoeff.bin
-emiscoef_IRland=$fixcrtm/NPOESS.IRland.EmisCoeff.bin
-emiscoef_IRsnow=$fixcrtm/NPOESS.IRsnow.EmisCoeff.bin
-emiscoef_VISice=$fixcrtm/NPOESS.VISice.EmisCoeff.bin
-emiscoef_VISland=$fixcrtm/NPOESS.VISland.EmisCoeff.bin
-emiscoef_VISsnow=$fixcrtm/NPOESS.VISsnow.EmisCoeff.bin
-emiscoef_VISwater=$fixcrtm/NPOESS.VISwater.EmisCoeff.bin
-emiscoef_MWwater=$fixcrtm/FASTEM6.MWwater.EmisCoeff.bin
-aercoef=$fixcrtm/AerosolCoeff.bin
-cldcoef=$fixcrtm/CloudCoeff.bin
-satinfo=$fixgsi/hwrf_satinfo.txt
-cloudyinfo=$fixgsi/cloudy_radiance_info.txt
-atmsbeaminfo=$fixgsi/atms_beamwidth.txt
-scaninfo=$fixgsi/global_scaninfo.txt
-pcpinfo=$fixgsi/nam_global_pcpinfo.txt
-ozinfo=$fixgsi/global_ozinfo.txt
-errtable=$fixgsi/hwrf_nam_errtable.r3dv
-convinfo=$fixgsi/hwrf_convinfo.txt
-### add 9 tables
-errtable_pw=$fixgsi/prepobs_errtable_pw.global
-errtable_ps=$fixgsi/prepobs_errtable_ps.global_nqcf
-errtable_t=$fixgsi/prepobs_errtable_t.global_nqcf
-errtable_q=$fixgsi/prepobs_errtable_q.global_nqcf
-errtable_uv=$fixgsi/prepobs_errtable_uv.global_nqcf
-btable_ps=$fixgsi/nqc_b_ps.global_nqcf
-btable_t=$fixgsi/nqc_b_t.global_nqcf
-btable_q=$fixgsi/nqc_b_q.global_nqcf
-btable_uv=$fixgsi/nqc_b_uv.global_nqcf
-
-# add vertical profile of localization and beta_s,beta_e weights for hybrid ensemble runs
-hybens_info=$fixgsi/hwrf_hybens_d2_info
-
-
-# Only need this file for single obs test
-bufrtable=$fixgsi/prepobs_prep.bufrtable
-
-# Only need this file for sst retrieval
-bftab_sst=$fixgsi/bufrtab.012
-
-# Copy executable and fixed files to $tmpdir
-if [[ $exp == *"updat"* ]]; then
- $ncp $gsiexec_updat ./gsi.x
-elif [[ $exp == *"contrl"* ]]; then
- $ncp $gsiexec_contrl ./gsi.x
-fi
-
-$ncp $anavinfo ./anavinfo
-$ncp $berror ./berror_stats
-$ncp $emiscoef_IRwater ./Nalli.IRwater.EmisCoeff.bin
-$ncp $emiscoef_IRice ./NPOESS.IRice.EmisCoeff.bin
-$ncp $emiscoef_IRsnow ./NPOESS.IRsnow.EmisCoeff.bin
-$ncp $emiscoef_IRland ./NPOESS.IRland.EmisCoeff.bin
-$ncp $emiscoef_VISice ./NPOESS.VISice.EmisCoeff.bin
-$ncp $emiscoef_VISland ./NPOESS.VISland.EmisCoeff.bin
-$ncp $emiscoef_VISsnow ./NPOESS.VISsnow.EmisCoeff.bin
-$ncp $emiscoef_VISwater ./NPOESS.VISwater.EmisCoeff.bin
-$ncp $emiscoef_MWwater ./FASTEM6.MWwater.EmisCoeff.bin
-$ncp $aercoef ./AerosolCoeff.bin
-$ncp $cldcoef ./CloudCoeff.bin
-$ncp $satinfo ./satinfo
-$ncp $cloudyinfo ./cloudy_radiance_info.txt
-$ncp $scaninfo ./scaninfo
-$ncp $pcpinfo ./pcpinfo
-$ncp $ozinfo ./ozinfo
-$ncp $convinfo ./convinfo
-$ncp $errtable ./errtable
-$ncp $atmsbeaminfo ./atms_beamwidth.txt
-
-#add 9 tables for new varqc
-$ncp $errtable_pw ./errtable_pw
-$ncp $errtable_ps ./errtable_ps
-$ncp $errtable_t ./errtable_t
-$ncp $errtable_q ./errtable_q
-$ncp $errtable_uv ./errtable_uv
-$ncp $btable_ps ./btable_ps
-$ncp $btable_t ./btable_t
-$ncp $btable_q ./btable_q
-$ncp $btable_uv ./btable_uv
-
-$ncp $hybens_info ./hybens_info
-
-$ncp $bufrtable ./prepobs_prep.bufrtable
-$ncp $bftab_sst ./bftab_sstphr
-
-# Copy CRTM coefficient files based on entries in satinfo file
-for file in `awk '{if($1!~"!"){print $1}}' ./satinfo | sort | uniq` ;do
- $ncp $fixcrtm/${file}.SpcCoeff.bin ./
- $ncp $fixcrtm/${file}.TauCoeff.bin ./
-done
-
-
-# Copy observational data to $tmpdir
-$lnsf $hwrf_nmm_obs/${prefixa}.prepbufr ./prepbufr
-$lnsf $hwrf_nmm_obs/${prefixa}.satwnd.${suffix} ./satwndbufr
-$lnsf $hwrf_nmm_obs/${prefixa}.gpsro.${suffix} ./gpsrobufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.spssmi.${suffix} ./ssmirrbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.sptrmm.${suffix} ./tmirrbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.gome.${suffix} ./gomebufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.omi.${suffix} ./omibufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.mls.${suffix} ./mlsbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.osbuv8.${suffix} ./sbuvbufr
-$lnsf $hwrf_nmm_obs/${prefixa}.goesfv.${suffix} ./gsnd1bufr
-$lnsf $hwrf_nmm_obs/${prefixa}.1bamua.${suffix} ./amsuabufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.1bamub.${suffix} ./amsubbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.1bhrs2.${suffix} ./hirs2bufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.1bhrs3.${suffix} ./hirs3bufr
-$lnsf $hwrf_nmm_obs/${prefixa}.1bhrs4.${suffix} ./hirs4bufr
-$lnsf $hwrf_nmm_obs/${prefixa}.1bmhs.${suffix} ./mhsbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.1bmsu.${suffix} ./msubufr
-$lnsf $hwrf_nmm_obs/${prefixa}.airsev.${suffix} ./airsbufr
-$lnsf $hwrf_nmm_obs/${prefixa}.sevcsr.${suffix} ./seviribufr
-$lnsf $hwrf_nmm_obs/${prefixa}.mtiasi.${suffix} ./iasibufr
-$lnsf $hwrf_nmm_obs/${prefixa}.esamua.${suffix} ./amsuabufrears
-$lnsf $hwrf_nmm_obs/${prefixa}.esamub.${suffix} ./amsubbufrears
-$lnsf $hwrf_nmm_obs/${prefixa}.eshrs3.${suffix} ./hirs3bufrears
-#$lnsf $hwrf_nmm_obs/${prefixa}.ssmit.${suffix} ./ssmitbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.amsre.${suffix} ./amsrebufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.ssmis.${suffix} ./ssmisbufr
-$lnsf $hwrf_nmm_obs/${prefixa}.atms.${suffix} ./atmsbufr
-$lnsf $hwrf_nmm_obs/${prefixa}.cris.${suffix} ./crisbufr
-$lnsf $hwrf_nmm_obs/${prefixa}.crisf4.${suffix} ./crisfsbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.syndata.tcvitals.tm00 ./tcvitl
-$lnsf $hwrf_nmm_obs/${prefixo}.tldplr.${suffix} ./tldplrbufr
-
-
-# Copy bias correction, atmospheric and surface files
-$lnsf $hwrf_nmm_obs/gdas1.t${hhg}z.abias ./satbias_in
-$lnsf $hwrf_nmm_obs/gdas1.t${hhg}z.abias_pc ./satbias_pc
-
-$ncp $hwrf_nmm_ges/wrfghost_d02_03 ./wrf_inou3
-$ncp $hwrf_nmm_ges/wrfghost_d02_06 ./wrf_inout
-$ncp $hwrf_nmm_ges/wrfghost_d02_09 ./wrf_inou9
-
-$ncp $hwrf_nmm_ges/gdas1.t${hhg}z.sf03 ./gfs_sigf03
-$ncp $hwrf_nmm_ges/gdas1.t${hhg}z.sf06 ./gfs_sigf06
-$ncp $hwrf_nmm_ges/gdas1.t${hhg}z.sf09 ./gfs_sigf09
-
-# Copy ensemble forecast files for hybrid analysis
-export ENSEMBLE_SIZE_REGIONAL=10
->filelist06
-n=1
-while [[ $n -le ${ENSEMBLE_SIZE_REGIONAL} ]]; do
- $lnsf $hwrf_nmm_ges/$( printf sfg_${gdate}_fhr06s_mem%03d $n ) \
- ./$( printf sfg_${gdate}_fhr06s_mem%03d $n )
- ls ./$( printf sfg_${gdate}_fhr06s_mem%03d $n ) >> filelist06
- n=$((n + 1))
-done
-
-# Run GSI
-cd $tmpdir
-echo "run gsi now"
-eval "$APRUN $tmpdir/gsi.x > stdout 2>&1"
-rc=$?
-exit $rc
-
-
-
-
-# Loop over first and last outer loops to generate innovation
-# diagnostic files for indicated observation types (groups)
-#
-# NOTE: Since we set miter=2 in GSI namelist SETUP, outer
-# loop 03 will contain innovations with respect to
-# the analysis. Creation of o-a innovation files
-# is triggered by write_diag(3)=.true. The setting
-# write_diag(1)=.true. turns on creation of o-g
-# innovation files.
-#
-
-
-echo "Time before diagnostic loop is `date` "
-cd $tmpdir
-loops="01 03"
-for loop in $loops; do
-
-case $loop in
- 01) string=ges;;
- 03) string=anl;;
- *) string=$loop;;
-esac
-
-# Collect diagnostic files for obs types (groups) below
- listall="hirs2_n14 msu_n14 sndr_g08 sndr_g11 sndr_g11 sndr_g12 sndr_g13 sndr_g08_prep sndr_g11_prep sndr_g12_prep sndr_g13_prep sndrd1_g11 sndrd2_g11 sndrd3_g11 sndrd4_g11 sndrd1_g12 sndrd2_g12 sndrd3_g12 sndrd4_g12 sndrd1_g13 sndrd2_g13 sndrd3_g13 sndrd4_g13 hirs3_n15 hirs3_n16 hirs3_n17 amsua_n15 amsua_n16 amsua_n17 amsub_n15 amsub_n16 amsub_n17 hsb_aqua airs_aqua amsua_aqua imgr_g08 imgr_g11 imgr_g12 pcp_ssmi_dmsp pcp_tmi_trmm conv sbuv2_n16 sbuv2_n17 sbuv2_n18 gome_metop-a omi_aura ssmi_f13 ssmi_f15 hirs4_n18 hirs4_metop-a amsua_n18 amsua_metop-a mhs_n18 mhs_metop-a amsre_low_aqua amsre_mid_aqua amsre_hig_aqua ssmis_las_f16 ssmis_uas_f16 ssmis_img_f16 ssmis_env_f16 iasi_metop-a"
- for type in $listall; do
- count=`ls dir.*/${type}_${loop}* | wc -l`
- if [[ $count -gt 0 ]]; then
- cat dir.*/${type}_${loop}* > diag_${type}_${string}.${hwrf_nmm_adate}
- compress diag_${type}_${string}.${hwrf_nmm_adate}
- $ncp diag_${type}_${string}.${hwrf_nmm_adate}.Z $savdir/
- fi
- done
-done
-echo "Time after diagnostic loop is `date` "
-
-
-
-# If requested, clean up $tmpdir
-if [[ "$CLEAN" = "YES" ]];then
- if [[ $rc -eq 0 ]];then
- rm -rf $tmpdir
- cd $tmpdir
- cd ../
- rmdir $tmpdir
- fi
-fi
-
-
-# End of script
-exit
diff --git a/regression/hwrf_nmm_d3.sh b/regression/hwrf_nmm_d3.sh
deleted file mode 100755
index 7b6746b741..0000000000
--- a/regression/hwrf_nmm_d3.sh
+++ /dev/null
@@ -1,337 +0,0 @@
-
-set -x
-
-# Set analysis date
-adate=$hwrf_nmm_adate
-
-io_format=netcdf
-
-if [[ "$io_format" = "binary" ]]; then
- NETCDF=.false.
- FORMAT=binary
-elif [[ "$io_format" = "netcdf" ]]; then
- NETCDF=.true.
- FORMAT=netcdf
-else
- echo "***ERRROR*** INVALID io_format = $io_format"
- exit
-fi
-
-# Set experiment name and analysis date
-
-exp=$jobname
-
-# Set path/file for gsi executable
-#gsiexec=$gsiexec
-
-# Set the JCAP resolution which you want.
-# All resolutions use LEVS=64
-#export JCAP=62
-export LEVS=60
-export JCAP_B=$JCAP
-export DELTIM=1200
-
-# Set runtime and save directories
-tmpdir=$tmpdir/tmpreg_hwrf_nmm_d3/${exp}
-savdir=$savdir/outreg_hwrf_nmm_d3/${exp}
-
-# Specify GSI fixed field and data directories.
-fixcrtm=${fixcrtm:-$CRTM_FIX}
-
-#datobs=$datobs
-
-# Set variables used in script
-# CLEAN up $tmpdir when finished (YES=remove, NO=leave alone)
-# ncp is cp replacement, currently keep as /bin/cp
-
-CLEAN=NO
-ncp=/bin/cp
-lnsf='ln -sf'
-
-NX3=250
-NY3=500
-export NLAT=$(( NY3 - 1 ))
-export NLON=$(( NX3 - 1 ))
-
-# Given the analysis date, compute the date from which the
-# first guess comes. Extract cycle and set prefix and suffix
-# for guess and observation data files
-gdate=`date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2} - 6 hours"`
-hha=`echo $adate | cut -c9-10`
-hhg=`echo $gdate | cut -c9-10`
-prefixa=gfs.t${hha}z
-prefixo=gdas1.t${hha}z
-suffix=tm00.bufr_d
-
-
-# Set up $tmpdir
-rm -rf $tmpdir
-mkdir -p $tmpdir
-cd $tmpdir
-rm -rf core*
-
-# Make gsi namelist
-
-. $scripts/regression_nl_update.sh
-
-GRIDOPTS="$GRIDOPTS_update"
-BKGVERR="$BKGVERR_update"
-ANBKGERR="$ANBKERR_update"
-JCOPTS="$JCOPTS_update"
-STRONGOPTS="$STRONGOPTS_update"
-OBSQC="$OBSQC_update"
-OBSINPUT="$OBSINPUT_update"
-SUPERRAD="$SUPERRAD_update"
-SINGLEOB="$SINGLEOB_update"
-
-# parameters for radiance data assimilation
-export SETUP="newpc4pred=.true., adp_anglebc=.true., angord=4, \
- passive_bc=.false., use_edges=.false., emiss_bc=.true., \
- diag_precon=.true., step_start=1.e-3, upd_pred(1)=0, \
- upd_pred(2)=0,upd_pred(3)=0,upd_pred(4)=0, \
- upd_pred(5)=0,upd_pred(6)=0,upd_pred(7)=0, \
- upd_pred(8)=0,upd_pred(9)=0,upd_pred(10)=0, \
- upd_pred(11)=0,upd_pred(12)=0,"
-
-export USE_GFS_STRATOSPHERE=".false."
-export USE_GFS_OZONE=".false."
-export REGIONAL_OZONE=".false."
-
-if [ "$debug" = ".false." ]; then
- . $scripts/regression_namelists.sh hwrf_nmm_d3
-else
- . $scripts/regression_namelists_db.sh hwrf_nmm_d3
-fi
-
-cat << EOF > gsiparm.anl
-
-$gsi_namelist
-
-EOF
-
-# Set fixed files
-# berror = forecast model background error statistics
-# specoef = CRTM spectral coefficients
-# trncoef = CRTM transmittance coefficients
-# emiscoef = CRTM coefficients for IR sea surface emissivity model
-# aerocoef = CRTM coefficients for aerosol effects
-# cldcoef = CRTM coefficients for cloud effects
-# satinfo = text file with information about assimilation of brightness temperatures
-# cloudyinfo = text file with information about assimilation of cloudy radiance
-# pcpinfo = text file with information about assimilation of prepcipitation rates
-# ozinfo = text file with information about assimilation of ozone data
-# errtable = text file with obs error for conventional data (optional)
-# convinfo = text file with information about assimilation of conventional data
-# bufrtable= text file ONLY needed for single obs test (oneobstest=.true.)
-# bftab_sst= bufr table for sst ONLY needed for sst retrieval (retrieval=.true.)
-
-anavinfo=$fixgsi/anavinfo_hwrf_L60_nooz
-berror=$fixgsi/$endianness/nam_glb_berror.f77.gcv
-emiscoef_IRwater=$fixcrtm/Nalli.IRwater.EmisCoeff.bin
-emiscoef_IRice=$fixcrtm/NPOESS.IRice.EmisCoeff.bin
-emiscoef_IRland=$fixcrtm/NPOESS.IRland.EmisCoeff.bin
-emiscoef_IRsnow=$fixcrtm/NPOESS.IRsnow.EmisCoeff.bin
-emiscoef_VISice=$fixcrtm/NPOESS.VISice.EmisCoeff.bin
-emiscoef_VISland=$fixcrtm/NPOESS.VISland.EmisCoeff.bin
-emiscoef_VISsnow=$fixcrtm/NPOESS.VISsnow.EmisCoeff.bin
-emiscoef_VISwater=$fixcrtm/NPOESS.VISwater.EmisCoeff.bin
-emiscoef_MWwater=$fixcrtm/FASTEM6.MWwater.EmisCoeff.bin
-aercoef=$fixcrtm/AerosolCoeff.bin
-cldcoef=$fixcrtm/CloudCoeff.bin
-satinfo=$fixgsi/hwrf_satinfo.txt
-cloudyinfo=$fixgsi/cloudy_radiance_info.txt
-atmsbeaminfo=$fixgsi/atms_beamwidth.txt
-scaninfo=$fixgsi/global_scaninfo.txt
-pcpinfo=$fixgsi/nam_global_pcpinfo.txt
-ozinfo=$fixgsi/global_ozinfo.txt
-errtable=$fixgsi/hwrf_nam_errtable.r3dv
-convinfo=$fixgsi/hwrf_convinfo.txt
-### add 9 tables
-errtable_pw=$fixgsi/prepobs_errtable_pw.global
-errtable_ps=$fixgsi/prepobs_errtable_ps.global_nqcf
-errtable_t=$fixgsi/prepobs_errtable_t.global_nqcf
-errtable_q=$fixgsi/prepobs_errtable_q.global_nqcf
-errtable_uv=$fixgsi/prepobs_errtable_uv.global_nqcf
-btable_ps=$fixgsi/nqc_b_ps.global_nqcf
-btable_t=$fixgsi/nqc_b_t.global_nqcf
-btable_q=$fixgsi/nqc_b_q.global_nqcf
-btable_uv=$fixgsi/nqc_b_uv.global_nqcf
-
-# add vertical profile of localization and beta_s,beta_e weights for hybrid ensemble runs
-hybens_info=$fixgsi/hwrf_hybens_d3_info
-
-
-# Only need this file for single obs test
-bufrtable=$fixgsi/prepobs_prep.bufrtable
-
-# Only need this file for sst retrieval
-bftab_sst=$fixgsi/bufrtab.012
-
-# Copy executable and fixed files to $tmpdir
-if [[ $exp == *"updat"* ]]; then
- $ncp $gsiexec_updat ./gsi.x
-elif [[ $exp == *"contrl"* ]]; then
- $ncp $gsiexec_contrl ./gsi.x
-fi
-
-$ncp $anavinfo ./anavinfo
-$ncp $berror ./berror_stats
-$ncp $emiscoef_IRwater ./Nalli.IRwater.EmisCoeff.bin
-$ncp $emiscoef_IRice ./NPOESS.IRice.EmisCoeff.bin
-$ncp $emiscoef_IRsnow ./NPOESS.IRsnow.EmisCoeff.bin
-$ncp $emiscoef_IRland ./NPOESS.IRland.EmisCoeff.bin
-$ncp $emiscoef_VISice ./NPOESS.VISice.EmisCoeff.bin
-$ncp $emiscoef_VISland ./NPOESS.VISland.EmisCoeff.bin
-$ncp $emiscoef_VISsnow ./NPOESS.VISsnow.EmisCoeff.bin
-$ncp $emiscoef_VISwater ./NPOESS.VISwater.EmisCoeff.bin
-$ncp $emiscoef_MWwater ./FASTEM6.MWwater.EmisCoeff.bin
-$ncp $aercoef ./AerosolCoeff.bin
-$ncp $cldcoef ./CloudCoeff.bin
-$ncp $satinfo ./satinfo
-$ncp $cloudyinfo ./cloudy_radiance_info.txt
-$ncp $scaninfo ./scaninfo
-$ncp $pcpinfo ./pcpinfo
-$ncp $ozinfo ./ozinfo
-$ncp $convinfo ./convinfo
-$ncp $errtable ./errtable
-$ncp $atmsbeaminfo ./atms_beamwidth.txt
-#add 9 tables for new varqc
-$ncp $errtable_pw ./errtable_pw
-$ncp $errtable_ps ./errtable_ps
-$ncp $errtable_t ./errtable_t
-$ncp $errtable_q ./errtable_q
-$ncp $errtable_uv ./errtable_uv
-$ncp $btable_ps ./btable_ps
-$ncp $btable_t ./btable_t
-$ncp $btable_q ./btable_q
-$ncp $btable_uv ./btable_uv
-
-$ncp $hybens_info ./hybens_info
-
-$ncp $bufrtable ./prepobs_prep.bufrtable
-$ncp $bftab_sst ./bftab_sstphr
-
-# Copy CRTM coefficient files based on entries in satinfo file
-for file in `awk '{if($1!~"!"){print $1}}' ./satinfo | sort | uniq` ;do
- $ncp $fixcrtm/${file}.SpcCoeff.bin ./
- $ncp $fixcrtm/${file}.TauCoeff.bin ./
-done
-
-
-# Copy observational data to $tmpdir
-$lnsf $hwrf_nmm_obs/${prefixa}.prepbufr ./prepbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.satwnd.${suffix} ./satwndbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.gpsro.${suffix} ./gpsrobufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.spssmi.${suffix} ./ssmirrbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.sptrmm.${suffix} ./tmirrbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.gome.${suffix} ./gomebufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.omi.${suffix} ./omibufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.mls.${suffix} ./mlsbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.osbuv8.${suffix} ./sbuvbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.goesfv.${suffix} ./gsnd1bufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.1bamua.${suffix} ./amsuabufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.1bamub.${suffix} ./amsubbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.1bhrs2.${suffix} ./hirs2bufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.1bhrs3.${suffix} ./hirs3bufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.1bhrs4.${suffix} ./hirs4bufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.1bmhs.${suffix} ./mhsbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.1bmsu.${suffix} ./msubufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.airsev.${suffix} ./airsbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.sevcsr.${suffix} ./seviribufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.mtiasi.${suffix} ./iasibufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.esamua.${suffix} ./amsuabufrears
-#$lnsf $hwrf_nmm_obs/${prefixa}.esamub.${suffix} ./amsubbufrears
-#$lnsf $hwrf_nmm_obs/${prefixa}.eshrs3.${suffix} ./hirs3bufrears
-#$lnsf $hwrf_nmm_obs/${prefixa}.ssmit.${suffix} ./ssmitbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.amsre.${suffix} ./amsrebufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.ssmis.${suffix} ./ssmisbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.atms.${suffix} ./atmsbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.cris.${suffix} ./crisbufr
-#$lnsf $hwrf_nmm_obs/${prefixa}.syndata.tcvitals.tm00 ./tcvitl
-$lnsf $hwrf_nmm_obs/${prefixo}.tldplr.${suffix} ./tldplrbufr
-
-
-# Copy bias correction, atmospheric and surface files
-$lnsf $hwrf_nmm_obs/gdas1.t${hhg}z.abias ./satbias_in
-$lnsf $hwrf_nmm_obs/gdas1.t${hhg}z.abias_pc ./satbias_pc
-
-$ncp $hwrf_nmm_ges/wrfghost_d03_03 ./wrf_inou3
-$ncp $hwrf_nmm_ges/wrfghost_d03_06 ./wrf_inout
-$ncp $hwrf_nmm_ges/wrfghost_d03_09 ./wrf_inou9
-
-$ncp $hwrf_nmm_ges/gdas1.t${hhg}z.sf03 ./gfs_sigf03
-$ncp $hwrf_nmm_ges/gdas1.t${hhg}z.sf06 ./gfs_sigf06
-$ncp $hwrf_nmm_ges/gdas1.t${hhg}z.sf09 ./gfs_sigf09
-
-# Copy ensemble forecast files for hybrid analysis
-export ENSEMBLE_SIZE_REGIONAL=10
->filelist06
-n=1
-while [[ $n -le ${ENSEMBLE_SIZE_REGIONAL} ]]; do
- $lnsf $hwrf_nmm_ges/$( printf sfg_${gdate}_fhr06s_mem%03d $n ) \
- ./$( printf sfg_${gdate}_fhr06s_mem%03d $n )
- ls ./$( printf sfg_${gdate}_fhr06s_mem%03d $n ) >> filelist06
- n=$((n + 1))
-done
-
-# Run GSI
-cd $tmpdir
-echo "run gsi now"
-eval "$APRUN $tmpdir/gsi.x > stdout 2>&1"
-rc=$?
-exit $rc
-
-
-
-
-# Loop over first and last outer loops to generate innovation
-# diagnostic files for indicated observation types (groups)
-#
-# NOTE: Since we set miter=2 in GSI namelist SETUP, outer
-# loop 03 will contain innovations with respect to
-# the analysis. Creation of o-a innovation files
-# is triggered by write_diag(3)=.true. The setting
-# write_diag(1)=.true. turns on creation of o-g
-# innovation files.
-#
-
-
-echo "Time before diagnostic loop is `date` "
-cd $tmpdir
-loops="01 03"
-for loop in $loops; do
-
-case $loop in
- 01) string=ges;;
- 03) string=anl;;
- *) string=$loop;;
-esac
-
-# Collect diagnostic files for obs types (groups) below
- listall="hirs2_n14 msu_n14 sndr_g08 sndr_g11 sndr_g11 sndr_g12 sndr_g13 sndr_g08_prep sndr_g11_prep sndr_g12_prep sndr_g13_prep sndrd1_g11 sndrd2_g11 sndrd3_g11 sndrd4_g11 sndrd1_g12 sndrd2_g12 sndrd3_g12 sndrd4_g12 sndrd1_g13 sndrd2_g13 sndrd3_g13 sndrd4_g13 hirs3_n15 hirs3_n16 hirs3_n17 amsua_n15 amsua_n16 amsua_n17 amsub_n15 amsub_n16 amsub_n17 hsb_aqua airs_aqua amsua_aqua imgr_g08 imgr_g11 imgr_g12 pcp_ssmi_dmsp pcp_tmi_trmm conv sbuv2_n16 sbuv2_n17 sbuv2_n18 gome_metop-a omi_aura ssmi_f13 ssmi_f15 hirs4_n18 hirs4_metop-a amsua_n18 amsua_metop-a mhs_n18 mhs_metop-a amsre_low_aqua amsre_mid_aqua amsre_hig_aqua ssmis_las_f16 ssmis_uas_f16 ssmis_img_f16 ssmis_env_f16 iasi_metop-a"
- for type in $listall; do
- count=`ls dir.*/${type}_${loop}* | wc -l`
- if [[ $count -gt 0 ]]; then
- cat dir.*/${type}_${loop}* > diag_${type}_${string}.${hwrf_nmm_adate}
- compress diag_${type}_${string}.${hwrf_nmm_adate}
- $ncp diag_${type}_${string}.${hwrf_nmm_adate}.Z $savdir/
- fi
- done
-done
-echo "Time after diagnostic loop is `date` "
-
-
-
-# If requested, clean up $tmpdir
-if [[ "$CLEAN" = "YES" ]];then
- if [[ $rc -eq 0 ]];then
- rm -rf $tmpdir
- cd $tmpdir
- cd ../
- rmdir $tmpdir
- fi
-fi
-
-
-# End of script
-exit
diff --git a/regression/multi_regression.sh b/regression/multi_regression.sh
index b850863d69..d01492aa44 100755
--- a/regression/multi_regression.sh
+++ b/regression/multi_regression.sh
@@ -1,22 +1,18 @@
#!/bin/sh --login
-regtests_all="global_3dvar
- global_4dvar
- global_4denvar
- netcdf_fv3_regional
- rrfs_3denvar_glbens
- hwrf_nmm_d2
- hwrf_nmm_d3
+regtests_all="global_4denvar
+ rrfs_3denvar_rdasens
+ hafs_4denvar_glbens
+ hafs_3denvar_hybens
rtma
global_enkf"
-regtests_debug="global_3dvar
- global_4dvar
- global_4denvar
- netcdf_fv3_regional
- rrfs_3denvar_glbens
- hwrf_nmm_d2
- hwrf_nmm_d3
+# rrfs_enkf_conv : comment out RRFS enkf case for now
+# need to update EnKF code
+regtests_debug="global_4denvar
+ rrfs_3denvar_rdasens
+ hafs_4denvar_glbens
+ hafs_3denvar_hybens
rtma
global_enkf"
diff --git a/regression/netcdf_fv3_regional.sh b/regression/netcdf_fv3_regional.sh
deleted file mode 100755
index db5ecb920a..0000000000
--- a/regression/netcdf_fv3_regional.sh
+++ /dev/null
@@ -1,217 +0,0 @@
-
-set -x
-
-# Set analysis date
-#adate=2015061000
-
-# Set experiment name
-exp=$jobname
-
-#TM=00
-#TM2=03
-#tmmark=tm${TM}
-
-
-# Set path/file for gsi executable
-#gsiexec=/meso/save/Wanshu.Wu/Code/trunk/trunk_40320/src/global_gsi_org
-#gsiexec=/da/save/Michael.Lueken/trunk/src/global_gsi.x
-
-# Set runtime and save directories
-tmpdir=$tmpdir/tmpreg_netcdf_fv3_regional/${exp}
-savdir=$savdir/outreg_netcdf_fv3_regional/${exp}
-
-# Set variables used in script
-# CLEAN up $tmpdir when finished (YES=remove, NO=leave alone)
-# ncp is cp replacement, currently keep as /bin/cp
-
-UNCOMPRESS=gunzip
-CLEAN=NO
-ncp=/bin/cp
-
-
-# Set up $tmpdir
-rm -rf $tmpdir
-mkdir -p $tmpdir
-chgrp rstprod $tmpdir
-chmod 750 $tmpdir
-cd $tmpdir
-
-#FIXnam=/da/save/Michael.Lueken/trunk/fix
-fixcrtm=${fixcrtm:-$CRTM_FIX}
-
-berror=$fixgsi/nam_nmm_berror.f77.gcv
-anavinfo=$fixgsi/anavinfo_fv3
-
-
-# Make gsi namelist
-
-. $scripts/regression_nl_update.sh
-
-SETUP="$SETUP_update"
-GRIDOPTS="$GRIDOPTS_update"
-BKGVERR="$BKGVERR_update"
-ANBKGERR="$ANBKERR_update"
-JCOPTS="$JCOPTS_update"
-STRONGOPTS="$STRONGOPTS_update"
-OBSQC="$OBSQC_update"
-OBSINPUT="$OBSINPUT_update"
-SUPERRAD="$SUPERRAD_update"
-HYBRID_ENSEMBLE='ensemble_path="",'
-SINGLEOB="$SINGLEOB_update"
-
-if [ "$debug" = ".false." ]; then
- . $scripts/regression_namelists.sh netcdf_fv3_regional
-else
- . $scripts/regression_namelists_db.sh netcdf_fv3_regional
-fi
-
-# dmesh(1)=120.0,time_window_max=1.5,ext_sonde=.true.,
-
-cat << EOF > gsiparm.anl
-
-$gsi_namelist
-
-EOF
-
-emiscoef_IRwater=$fixcrtm/Nalli.IRwater.EmisCoeff.bin
-emiscoef_IRice=$fixcrtm/NPOESS.IRice.EmisCoeff.bin
-emiscoef_IRland=$fixcrtm/NPOESS.IRland.EmisCoeff.bin
-emiscoef_IRsnow=$fixcrtm/NPOESS.IRsnow.EmisCoeff.bin
-emiscoef_VISice=$fixcrtm/NPOESS.VISice.EmisCoeff.bin
-emiscoef_VISland=$fixcrtm/NPOESS.VISland.EmisCoeff.bin
-emiscoef_VISsnow=$fixcrtm/NPOESS.VISsnow.EmisCoeff.bin
-emiscoef_VISwater=$fixcrtm/NPOESS.VISwater.EmisCoeff.bin
-emiscoef_MWwater=$fixcrtm/FASTEM6.MWwater.EmisCoeff.bin
-aercoef=$fixcrtm/AerosolCoeff.bin
-cldcoef=$fixcrtm/CloudCoeff.bin
-satinfo=$fixgsi/nam_regional_satinfo.txt
-cloudyinfo=$fixgsi/cloudy_radiance_info.txt
-scaninfo=$fixgsi/global_scaninfo.txt
-pcpinfo=$fixgsi/nam_global_pcpinfo.txt
-ozinfo=$fixgsi/nam_global_ozinfo.txt
-errtable=$fixgsi/nam_errtable.r3dv
-convinfo=$fixgsi/nam_regional_convinfo.txt
-mesonetuselist=$fixgsi/nam_mesonet_uselist.txt
-stnuselist=$fixgsi/nam_mesonet_stnuselist.txt
-qdaylist=$fixgsi/rtma_q_day_rejectlist
-qnightlist=$fixgsi/rtma_q_night_rejectlist
-tdaylist=$fixgsi/rtma_t_day_rejectlist
-tnightlist=$fixgsi/rtma_t_night_rejectlist
-wbinuselist=$fixgsi/rtma_wbinuselist
-locinfo=$fixgsi/nam_hybens_d01_locinfo
-### add 9 tables
-errtable_pw=$fixgsi/prepobs_errtable_pw.global
-errtable_ps=$fixgsi/prepobs_errtable_ps.global_nqcf
-errtable_t=$fixgsi/prepobs_errtable_t.global_nqcf
-errtable_q=$fixgsi/prepobs_errtable_q.global_nqcf
-errtable_uv=$fixgsi/prepobs_errtable_uv.global_nqcf
-btable_ps=$fixgsi/nqc_b_ps.global_nqcf
-btable_t=$fixgsi/nqc_b_t.global_nqcf
-btable_q=$fixgsi/nqc_b_q.global_nqcf
-btable_uv=$fixgsi/nqc_b_uv.global_nqcf
-
-# add vertical profile of localization and beta_s,beta_e weights for hybrid ensemble runs
-hybens_info=$fixgsi/nam_hybens_d01_info
-
-
-# Copy executable and fixed files to $tmpdir
-if [[ $exp == *"updat"* ]]; then
- $ncp $gsiexec_updat ./gsi.x
-elif [[ $exp == *"contrl"* ]]; then
- $ncp $gsiexec_contrl ./gsi.x
-fi
-
-cp $anavinfo ./anavinfo
-cp $berror ./berror_stats
-cp $errtable ./errtable
-cp $emiscoef_IRwater ./Nalli.IRwater.EmisCoeff.bin
-cp $emiscoef_IRice ./NPOESS.IRice.EmisCoeff.bin
-cp $emiscoef_IRsnow ./NPOESS.IRsnow.EmisCoeff.bin
-cp $emiscoef_IRland ./NPOESS.IRland.EmisCoeff.bin
-cp $emiscoef_VISice ./NPOESS.VISice.EmisCoeff.bin
-cp $emiscoef_VISland ./NPOESS.VISland.EmisCoeff.bin
-cp $emiscoef_VISsnow ./NPOESS.VISsnow.EmisCoeff.bin
-cp $emiscoef_VISwater ./NPOESS.VISwater.EmisCoeff.bin
-cp $emiscoef_MWwater ./FASTEM6.MWwater.EmisCoeff.bin
-cp $aercoef ./AerosolCoeff.bin
-cp $cldcoef ./CloudCoeff.bin
-cp $satinfo ./satinfo
-cp $cloudyinfo ./cloudy_radiance_info.txt
-cp $scaninfo ./scaninfo
-cp $pcpinfo ./pcpinfo
-cp $ozinfo ./ozinfo
-cp $convinfo ./convinfo
-cp $mesonetuselist ./mesonetuselist
-cp $stnuselist ./mesonet_stnuselist
-cp $qdaylist ./q_day_rejectlist
-cp $qnightlist ./q_night_rejectlist
-cp $tdaylist ./t_day_rejectlist
-cp $tnightlist ./t_night_rejectlist
-cp $wbinuselist ./wbinuselist
-#cp $locinfo ./hybens_info
-#add 9 tables for new varqc
-$ncp $errtable_pw ./errtable_pw
-$ncp $errtable_ps ./errtable_ps
-$ncp $errtable_t ./errtable_t
-$ncp $errtable_q ./errtable_q
-$ncp $errtable_uv ./errtable_uv
-$ncp $btable_ps ./btable_ps
-$ncp $btable_t ./btable_t
-$ncp $btable_q ./btable_q
-$ncp $btable_uv ./btable_uv
-
-$ncp $hybens_info ./hybens_info
-
-
-###### crtm coeff's #######################
-set +x
-for file in `awk '{if($1!~"!"){print $1}}' satinfo | sort | uniq` ;do
- cp $fixcrtm/${file}.SpcCoeff.bin ./
- cp $fixcrtm/${file}.TauCoeff.bin ./
-done
-set -x
-
-PDY=`echo $adate | cut -c1-8`
-CYC=`echo $adate | cut -c9-10`
-
-#datdir=/meso/noscrub/Wanshu.Wu/CASE/$adate
-
-cp $fv3_netcdf_obs/ndas.t06z.radwnd.tm06.bufr_d ./radarbufr
-cp $fv3_netcdf_obs/ndas.t06z.prepbufr.tm06 ./prepbufr
-cp $fv3_netcdf_obs/ndas.t06z.1bamua.tm06.bufr_d ./amsuabufr
-cp $fv3_netcdf_obs/ndas.t06z.1bmhs.tm06.bufr_d ./mhsbufr
-cp $fv3_netcdf_obs/ndas.t06z.1bhrs4.tm06.bufr_d ./hirs4bufr
-cp $fv3_netcdf_obs/ndas.t06z.goesfv.tm06.bufr_d ./gsnd1bufr
-cp $fv3_netcdf_obs/ndas.t06z.airsev.tm06.bufr_d ./airsbufr
-cp $fv3_netcdf_obs/ndas.t06z.satwnd.tm06.bufr_d ./satwndbufr
-
-cp $fv3_netcdf_ges/coupler.res coupler.res
-cp $fv3_netcdf_ges/fv_core.res.nest02.nc fv3_akbk
-cp $fv3_netcdf_ges/grid_spec.nest02.nc fv3_grid_spec
-#the current GSI parallel IO for fv3-lam require the netcdf 4 format for nc files containing 3d fields
-nccopy -4 $fv3_netcdf_ges/fv_core.res.nest02.tile7.nc fv3_dynvars
-nccopy -4 $fv3_netcdf_ges/fv_tracer.res.nest02.tile7.nc fv3_tracer
-cp $fv3_netcdf_ges/sfc_data.nest02.tile7.nc fv3_sfcdata
-
-
-cp $fv3_netcdf_ges/nam.t06z.satbias_pc.tm04 ./satbias_pc
-cp $fv3_netcdf_ges/nam.t06z.satbias.tm04 ./satbias_in
-cp $fv3_netcdf_ges/nam.t06z.radstat.tm04 ./radstat.gdas
-
-listdiag=`tar xvf radstat.gdas | cut -d' ' -f2 | grep _ges`
-for type in $listdiag; do
- diag_file=`echo $type | cut -d',' -f1`
- fname=`echo $diag_file | cut -d'.' -f1`
- date=`echo $diag_file | cut -d'.' -f2`
- $UNCOMPRESS $diag_file
- fnameanl=$(echo $fname|sed 's/_ges//g')
- mv $fname.$date $fnameanl
-done
-
-
-# Run GSI
-cd $tmpdir
-echo "run gsi now"
-eval "$APRUN $tmpdir/gsi.x > stdout 2>&1"
-rc=$?
-exit $rc
diff --git a/regression/regression_driver.sh b/regression/regression_driver.sh
index 621ccbf485..805a9dd1fb 100755
--- a/regression/regression_driver.sh
+++ b/regression/regression_driver.sh
@@ -35,9 +35,13 @@ for jn in `seq ${RSTART} ${REND}`; do
if [ $jn -le 2 ]; then
export scripts=${scripts_updat:-$scripts}
export fixgsi=${fixgsi_updat:-$fixgsi}
+ export modulefiles=${modulefiles_updat:-$modulefiles}
+ export ush=${ush_update:-$ush}
else
export scripts=${scripts_contrl:-$scripts}
export fixgsi=${fixgsi_contrl:-$fixgsi}
+ export modulefiles=${modulefiles_contrl:-$modulefiles}
+ export ush=${ush_cntrl:-$ush}
fi
rm -f ${job[$jn]}.out
@@ -47,7 +51,6 @@ for jn in `seq ${RSTART} ${REND}`; do
$scripts/regression_wait.sh ${job[$jn]} ${rcname} $check_resource
rc=$?
if [ $rc -ne 0 ]; then
- rm -f ${rcname}
exit 1
fi
done
@@ -56,7 +59,7 @@ if [ "$debug" == ".false." ]; then
export scripts=${scripts_updat:-$scripts}
- if [ $regtest = 'global_enkf' ]; then
+ if [ $regtest = 'global_enkf' ] || [ $regtest = 'rrfs_enkf_conv' ]; then
/bin/sh $scripts/regression_test_enkf.sh ${job[1]} ${job[2]} ${job[3]} ${job[4]} ${tmpregdir} ${result} ${scaling[1]} ${scaling[2]} ${scaling[3]}
else
/bin/sh $scripts/regression_test.sh ${job[1]} ${job[2]} ${job[3]} ${job[4]} ${tmpregdir} ${result} ${scaling[1]} ${scaling[2]} ${scaling[3]}
diff --git a/regression/regression_namelists.sh b/regression/regression_namelists.sh
index 824c6f0719..a4f283f92b 100755
--- a/regression/regression_namelists.sh
+++ b/regression/regression_namelists.sh
@@ -2,14 +2,14 @@ regtest=$1
case $regtest in
- global_3dvar)
+ global_4denvar)
-# Define namelist for global run (pcgsoi minimization)
+# Define namelist for global hybrid run
export gsi_namelist="
&SETUP
- miter=2,niter(1)=5,niter(2)=10,
+ miter=2,niter(1)=5,niter(2)=5,
niter_no_qc(1)=2,niter_no_qc(2)=0,
write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
qoption=2,
@@ -26,9 +26,12 @@ export gsi_namelist="
verbose=.false.,imp_physics=11,lupp=.true.,
binary_diag=.false.,netcdf_diag=.true.,
lobsdiag_forenkf=.false.,
- nhr_anal=3,6,9,nhr_obsbin=3,
+ nhr_anal=3,6,9,nhr_obsbin=1,
+ l4densvar=.true.,ens_nstarthr=3,nhr_assimilation=6,lwrite4danl=.true.,
optconv=0.05,cao_check=.true.,ta2tb=.false.,
- tzr_qc=1,sfcnst_comb=.true., write_fv3_incr=.true.,incvars_to_zero= 'liq_wat_inc','icmr_inc','rwmr_inc','snmr_inc','grle_inc',incvars_zero_strat='sphum_inc','liq_wat_inc','icmr_inc','rwmr_inc','snmr_inc','grle_inc',incvars_efold=5, use_gfs_ncio=.true.,
+ tzr_qc=1,sfcnst_comb=.true.,
+ write_fv3_incr=.true.,incvars_to_zero= 'liq_wat_inc','icmr_inc','rwmr_inc','snmr_inc','grle_inc',
+ incvars_zero_strat='sphum_inc','liq_wat_inc','icmr_inc','rwmr_inc','snmr_inc','grle_inc',incvars_efold=5, use_gfs_ncio=.true.,
$SETUP
/
&GRIDOPTS
@@ -56,7 +59,8 @@ export gsi_namelist="
$JCOPTS
/
&STRONGOPTS
- tlnmc_option=2,nstrong=1,nvmodes_keep=8,period_max=6.,period_width=1.5,
+ tlnmc_option=3,nstrong=1,nvmodes_keep=8,period_max=6.,period_width=1.5,
+
baldiag_full=.false.,baldiag_inc=.false.,
$STRONGOPTS
/
@@ -64,7 +68,7 @@ export gsi_namelist="
dfact=0.75,dfact1=3.0,noiqc=.true.,oberrflg=.false.,c_varqc=0.04,
use_poq7=.true.,qc_noirjaco3_pole=.true.,vqc=.false.,nvqc=.true.,hub_norm=.true.,
aircraft_t_bc=.true.,biaspredt=1.0e5,upd_aircraft=.true.,cleanup_tail=.true.,
- tcp_width=70.0,tcp_ermax=7.35,
+ tcp_width=70.0,tcp_ermax=7.35,cris_cads=.true.,iasi_cads=.true.,
$OBSQC
/
&OBS_INPUT
@@ -94,8 +98,6 @@ OBS_INPUT::
sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
- hirs3bufr hirs3 n17 hirs3_n17 0.0 1 0
- hirs4bufr hirs4 metop-a hirs4_metop-a 0.0 1 1
gimgrbufr goes_img g11 imgr_g11 0.0 1 0
gimgrbufr goes_img g12 imgr_g12 0.0 1 0
airsbufr airs aqua airs_aqua 0.0 1 1
@@ -129,7 +131,6 @@ OBS_INPUT::
gomebufr gome metop-a gome_metop-a 0.0 2 0
omibufr omi aura omi_aura 0.0 2 0
sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
- hirs4bufr hirs4 n19 hirs4_n19 0.0 1 1
amsuabufr amsua n19 amsua_n19 0.0 1 1
mhsbufr mhs n19 mhs_n19 0.0 1 1
tcvitl tcp null tcp 0.0 0 0
@@ -137,7 +138,6 @@ OBS_INPUT::
seviribufr seviri m09 seviri_m09 0.0 1 0
seviribufr seviri m10 seviri_m10 0.0 1 0
seviribufr seviri m11 seviri_m11 0.0 1 0
- hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 1
amsuabufr amsua metop-b amsua_metop-b 0.0 1 1
mhsbufr mhs metop-b mhs_metop-b 0.0 1 1
iasibufr iasi metop-b iasi_metop-b 0.0 1 1
@@ -195,7 +195,13 @@ OBS_INPUT::
/
&HYBRID_ENSEMBLE
- $HYBRIDENSEMBLE
+ l_hyb_ens=.true.,n_ens=$NMEM_ENKF,beta_s0=0.125,readin_beta=.false.,
+ generate_ens=.false.,uv_hyb_ens=.true.,jcap_ens=48,nlat_ens=98,nlon_ens=192,
+ ANISO_A_EN=.false.,jcap_ens_test=48,oz_univ_static=.false.,
+ ensemble_path='./ensemble_data/',ens_fast_read=.true.,write_ens_sprd=.false.,
+ s_ens_h=1000.0,450.0,685.0,s_ens_v=-0.5,-0.5,0.0,readin_localization=.false.,
+ global_spectral_filter_sd=.false.,r_ensloccov4scl=1,nsclgrp=2,naensloc=3,
+ $HYBRID_ENSEMBLE
/
&RAPIDREFRESH_CLDSURF
dfi_radar_latent_heat_time_period=30.0,
@@ -214,797 +220,17 @@ OBS_INPUT::
/
"
;;
+ RTMA)
- global_lanczos)
-
-# Define namelist for global run (lanczos minimization)
-
-export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=50,niter(2)=50,
- niter_no_qc(1)=500,niter_no_qc(2)=500,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- gencode=82,qoption=2,
- factqmin=0.005,factqmax=0.005,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,l_foto=.false.,
- use_pbl=.false.,use_compress=.false.,nsig_ext=10,gpstop=30.,
- crtm_coeffs_path='./crtm_coeffs/',
- lsqrtb=.true.,lcongrad=.true.,ltlint=.true.,ladtest=.true.,lgrtest=.false.,
- use_gfs_nemsio=.false.,lrun_subdirs=.true.,use_gfs_ncio=.true.,
- $SETUP
- /
- &GRIDOPTS
- JCAP=$JCAP,JCAP_B=$JCAP_B,NLAT=$NLAT,NLON=$LONA,nsig=$LEVS,
- regional=.false.,nlayers(63)=3,nlayers(64)=6,
- $GRIDOPTS
- /
- &BKGERR
- vs=0.7,
- hzscl=1.7,0.8,0.5,
- hswgt=0.45,0.3,0.25,
- bw=0.0,norsp=4,
- bkgv_flowdep=.true.,bkgv_rewgtfct=1.5,
- $BKGVERR
- /
- &ANBKGERR
- anisotropic=.false.,
- $ANBKGERR
- /
- &JCOPTS
- ljcpdry=.false.,bamp_jcpdry=2.5e7,
- $JCOPTS
- /
- &STRONGOPTS
- tlnmc_option=1,nstrong=1,nvmodes_keep=8,period_max=6.,period_width=1.5,
- baldiag_full=.true.,baldiag_inc=.true.,
- $STRONGOPTS
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.false.,oberrflg=.false.,c_varqc=0.02,
- use_poq7=.true.,njqc=.false.,vqc=.true.,
- $OBSQC
- /
- &OBS_INPUT
- dmesh(1)=180.0,dmesh(2)=145.0,dmesh(3)=240.0,dmesh(4)=160.0,dmesh(5)=180.0,dmesh(6)=150.0,dmesh(7)=145.0,time_window_max=3.0,
- $OBSINPUT
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 1.0 0 0
- prepbufr t null t 1.0 0 0
- prepbufr q null q 1.0 0 0
- prepbufr pw null pw 1.0 0 0
- satwndbufr uv null uv 1.0 0 0
- prepbufr uv null uv 1.0 0 0
- prepbufr spd null spd 1.0 0 0
- prepbufr dw null dw 1.0 0 0
- radarbufr rw null l3rw 1.0 0 0
- l2rwbufr rw null l2rw 1.0 0 0
- prepbufr sst null sst 1.0 0 0
- gpsrobufr $gps_dtype null gps 1.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 1.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 1.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 1.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 1.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 1.0 0 0
- hirs2bufr hirs2 n14 hirs2_n14 6.0 1 1
- hirs3bufr hirs3 n16 hirs3_n16 0.0 1 1
- hirs3bufr hirs3 n17 hirs3_n17 6.0 1 1
- hirs4bufr hirs4 n18 hirs4_n18 0.0 1 1
- hirs4bufr hirs4 metop-a hirs4_metop-a 6.0 1 1
- gsndrbufr sndr g11 sndr_g11 0.0 1 0
- gsndrbufr sndr g12 sndr_g12 0.0 1 0
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs_aqua 20.0 1 1
- msubufr msu n14 msu_n14 2.0 2 1
- amsuabufr amsua n15 amsua_n15 10.0 2 1
- amsuabufr amsua n16 amsua_n16 0.0 2 1
- amsuabufr amsua n17 amsua_n17 0.0 2 1
- amsuabufr amsua n18 amsua_n18 10.0 2 1
- amsuabufr amsua metop-a amsua_metop-a 10.0 2 1
- airsbufr amsua aqua amsua_aqua 5.0 2 1
- amsubbufr amsub n15 amsub_n15 3.0 3 1
- amsubbufr amsub n16 amsub_n16 3.0 3 1
- amsubbufr amsub n17 amsub_n17 3.0 3 1
- mhsbufr mhs n18 mhs_n18 3.0 3 1
- mhsbufr mhs metop-a mhs_metop-a 3.0 3 1
- ssmitbufr ssmi f13 ssmi_f13 0.0 4 0
- ssmitbufr ssmi f15 ssmi_f15 0.0 4 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 4 1
- amsrebufr amsre_mid aqua amsre_aqua 0.0 4 1
- amsrebufr amsre_hig aqua amsre_aqua 0.0 4 1
- ssmisbufr ssmis f16 ssmis_f16 0.0 4 1
- gsnd1bufr sndrd1 g12 sndrD1_g12 1.5 5 0
- gsnd1bufr sndrd2 g12 sndrD2_g12 1.5 5 0
- gsnd1bufr sndrd3 g12 sndrD3_g12 1.5 5 0
- gsnd1bufr sndrd4 g12 sndrD4_g12 1.5 5 0
- gsnd1bufr sndrd1 g11 sndrD1_g11 1.5 5 0
- gsnd1bufr sndrd2 g11 sndrD2_g11 1.5 5 0
- gsnd1bufr sndrd3 g11 sndrD3_g11 1.5 5 0
- gsnd1bufr sndrd4 g11 sndrD4_g11 1.5 5 0
- gsnd1bufr sndrd1 g13 sndrD1_g13 1.5 5 0
- gsnd1bufr sndrd2 g13 sndrD2_g13 1.5 5 0
- gsnd1bufr sndrd3 g13 sndrD3_g13 1.5 5 0
- gsnd1bufr sndrd4 g13 sndrD4_g13 1.5 5 0
- iasibufr iasi metop-a iasi_metop-a 20.0 1 1
- gomebufr gome metop-a gome_metop-a 1.0 6 0
- omibufr omi aura omi_aura 1.0 6 0
- sbuvbufr sbuv2 n19 sbuv8_n19 1.0 0 0
- hirs4bufr hirs4 n19 hirs4_n19 6.0 1 1
- amsuabufr amsua n19 amsua_n19 10.0 2 1
- mhsbufr mhs n19 mhs_n19 3.0 3 1
- tcvitl tcp null tcp 1.0 0 0
- mlsbufr mls30 aura mls30_aura 1.0 0 0
- seviribufr seviri m08 seviri_m08 0.0 7 0
- seviribufr seviri m09 seviri_m09 0.0 7 0
- seviribufr seviri m10 seviri_m10 0.0 7 0
- seviribufr seviri m11 seviri_m11 0.0 7 0
- oscatbufr uv null uv 1.0 0 0
- ompsnpbufr ompsnp npp ompsnp_npp 1.0 0 0
- ompstcbufr ompstc8 npp ompstc8_npp 1.0 6 0
- abibufr abi g16 abi_g16 0.0 7 0
- ahibufr ahi himawari8 ahi_himawari8 0.0 7 0
- abibufr abi g17 abi_g17 0.0 7 0
- abibufr abi g18 abi_g18 0.0 7 0
- ahibufr ahi himawari9 ahi_himawari9 0.0 7 0
- atmsbufr atms n21 atms_n21 0.0 7 1
- crisfsbufr cris-fsr n21 cris-fsr_n21 0.0 7 0
- sstviirs viirs-m j2 viirs-m_j2 0.0 4 0
- ompsnpbufr ompsnp n21 ompsnp_n21 0.0 0 0
- ompstcbufr ompstc8 n21 ompstc8_n21 0.0 6 0
- gomebufr gome metop-c gome_metop-c 0.0 6 0
-::
- &SUPEROB_RADAR
- $SUPERRAD
- /
- &LAG_DATA
- /
- &HYBRID_ENSEMBLE
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- /
- &CHEM
- /
- &SINGLEOB_TEST
- maginnov=0.1,magoberr=0.1,oneob_type='t',
- oblat=45.,oblon=180.,obpres=1000.,obdattim=${adate},
- obhourset=0.,
- $SINGLEOB
- /
- &NST
- /
-"
-
-;;
-
- global_hybrid_T126)
-
-# Define namelist for global hybrid run
+# Define namelist for RTMA runs
export gsi_namelist="
&SETUP
- miter=1,niter(1)=5,niter(2)=150,
- niter_no_qc(1)=50,niter_no_qc(2)=0,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- qoption=2,cwoption=3,
- gencode=82,factqmin=0.1,factqmax=0.1,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,l_foto=.false.,
- use_pbl=.false.,use_prepb_satwnd=.false.,
- nhr_assimilation=6,lrun_subdirs=.true.,
- $SETUP
- /
- &GRIDOPTS
- JCAP_B=$JCAP_B,JCAP=$JCAP,NLAT=$NLAT,NLON=$LONA,nsig=$LEVS,
- regional=.false.,nlayers(63)=3,nlayers(64)=6,
- $GRIDOPTS
- /
- &BKGERR
- hzscl=1.7,0.8,0.5,
- hswgt=0.45,0.3,0.25,
-
- bw=0.0,norsp=4,
- bkgv_flowdep=.true.,bkgv_rewgtfct=1.5,
- bkgv_write=.false.,
- $BKGVERR
- /
- &ANBKGERR
- anisotropic=.false.,
- $ANBKGERR
- /
- &JCOPTS
- ljcdfi=.false.,alphajc=0.0,ljcpdry=.true.,bamp_jcpdry=2.5e7,
- $JCOPTS
- /
- &STRONGOPTS
- tlnmc_option=1,nstrong=1,nvmodes_keep=8,period_max=6.,period_width=1.5,
- baldiag_full=.true.,baldiag_inc=.true.,
- $STRONGOPTS
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.true.,oberrflg=.false.,c_varqc=0.02,
- use_poq7=.true.,njqc=.false.,vqc=.true.,aircraft_t_bc=.true.,biaspredt=1000.0,upd_aircraft=.true.,
- $OBSQC
- /
- &OBS_INPUT
- dmesh(1)=145.0,dmesh(2)=150.0,time_window_max=3.0,
- $OBSINPUT
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 0.0 0 0
- prepbufr t null t 0.0 0 0
- prepbufr_profl t null t 0.0 0 0
- prepbufr q null q 0.0 0 0
- prepbufr_profl q null q 0.0 0 0
- prepbufr pw null pw 0.0 0 0
- prepbufr uv null uv 0.0 0 0
- prepbufr_profl uv null uv 0.0 0 0
- satwndbufr uv null uv 0.0 0 0
- prepbufr spd null spd 0.0 0 0
- prepbufr dw null dw 0.0 0 0
- radarbufr rw null l3rw 0.0 0 0
- l2rwbufr rw null l2rw 0.0 0 0
- prepbufr sst null sst 0.0 0 0
- gpsrobufr gps_bnd null gps 0.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
- hirs3bufr hirs3 n17 hirs3_n17 0.0 1 0
- hirs4bufr hirs4 metop-a hirs4_metop-a 0.0 1 1
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs_aqua 0.0 1 1
- amsuabufr amsua n15 amsua_n15 0.0 1 1
- amsuabufr amsua n18 amsua_n18 0.0 1 1
- amsuabufr amsua metop-a amsua_metop-a 0.0 1 1
- airsbufr amsua aqua amsua_aqua 0.0 1 1
- amsubbufr amsub n17 amsub_n17 0.0 1 1
- mhsbufr mhs n18 mhs_n18 0.0 1 1
- mhsbufr mhs metop-a mhs_metop-a 0.0 1 1
- ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_mid aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_hig aqua amsre_aqua 0.0 1 0
- ssmisbufr ssmis_las f16 ssmis_f16 0.0 1 0
- ssmisbufr ssmis_uas f16 ssmis_f16 0.0 1 0
- ssmisbufr ssmis_img f16 ssmis_f16 0.0 1 0
- ssmisbufr ssmis_env f16 ssmis_f16 0.0 1 0
- gsnd1bufr sndrd1 g12 sndrD1_g12 0.0 1 0
- gsnd1bufr sndrd2 g12 sndrD2_g12 0.0 1 0
- gsnd1bufr sndrd3 g12 sndrD3_g12 0.0 1 0
- gsnd1bufr sndrd4 g12 sndrD4_g12 0.0 1 0
- gsnd1bufr sndrd1 g11 sndrD1_g11 0.0 1 0
- gsnd1bufr sndrd2 g11 sndrD2_g11 0.0 1 0
- gsnd1bufr sndrd3 g11 sndrD3_g11 0.0 1 0
- gsnd1bufr sndrd4 g11 sndrD4_g11 0.0 1 0
- gsnd1bufr sndrd1 g13 sndrD1_g13 0.0 1 0
- gsnd1bufr sndrd2 g13 sndrD2_g13 0.0 1 0
- gsnd1bufr sndrd3 g13 sndrD3_g13 0.0 1 0
- gsnd1bufr sndrd4 g13 sndrD4_g13 0.0 1 0
- iasibufr iasi metop-a iasi_metop-a 0.0 1 1
- gomebufr gome metop-a gome_metop-a 0.0 2 0
- omibufr omi aura omi_aura 0.0 2 0
- sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
- hirs4bufr hirs4 n19 hirs4_n19 0.0 1 1
- amsuabufr amsua n19 amsua_n19 0.0 1 1
- mhsbufr mhs n19 mhs_n19 0.0 1 1
- tcvitl tcp null tcp 0.0 0 0
- seviribufr seviri m08 seviri_m08 0.0 1 0
- seviribufr seviri m09 seviri_m09 0.0 1 0
- seviribufr seviri m10 seviri_m10 0.0 1 0
- seviribufr seviri m11 seviri_m11 0.0 1 0
- hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 0
- amsuabufr amsua metop-b amsua_metop-b 0.0 1 0
- mhsbufr mhs metop-b mhs_metop-b 0.0 1 0
- iasibufr iasi metop-b iasi_metop-b 0.0 1 0
- gomebufr gome metop-b gome_metop-b 0.0 2 0
- atmsbufr atms npp atms_npp 0.0 1 0
- atmsbufr atms n20 atms_n20 0.0 1 0
- crisbufr cris npp cris_npp 0.0 1 0
- crisfsbufr cris-fsr npp cris-fsr_npp 0.0 1 0
- crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 1 0
- gsnd1bufr sndrd1 g14 sndrD1_g14 0.0 1 0
- gsnd1bufr sndrd2 g14 sndrD2_g14 0.0 1 0
- gsnd1bufr sndrd3 g14 sndrD3_g14 0.0 1 0
- gsnd1bufr sndrd4 g14 sndrD4_g14 0.0 1 0
- gsnd1bufr sndrd1 g15 sndrD1_g15 0.0 1 0
- gsnd1bufr sndrd2 g15 sndrD2_g15 0.0 1 0
- gsnd1bufr sndrd3 g15 sndrD3_g15 0.0 1 0
- gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 1 0
- ompsnpbufr ompsnp npp ompsnp_npp 0.0 0 0
- ompstcbufr ompstc8 npp ompstc8_npp 0.0 2 0
- abibufr abi g16 abi_g16 0.0 1 0
- ahibufr ahi himawari8 ahi_himawari8 0.0 1 0
- abibufr abi g17 abi_g17 0.0 1 0
- abibufr abi g18 abi_g18 0.0 1 0
- ahibufr ahi himawari9 ahi_himawari9 0.0 1 0
- atmsbufr atms n21 atms_n21 0.0 1 1
- crisfsbufr cris-fsr n21 cris-fsr_n21 0.0 1 0
- sstviirs viirs-m j2 viirs-m_j2 0.0 4 0
- ompsnpbufr ompsnp n21 ompsnp_n21 0.0 0 0
- ompstcbufr ompstc8 n21 ompstc8_n21 0.0 2 0
- gomebufr gome metop-c gome_metop-c 0.0 2 0
-::
- &SUPEROB_RADAR
- $SUPERRAD
- /
- &LAG_DATA
- $LAGDATA
- /
- &HYBRID_ENSEMBLE
- l_hyb_ens=.true.,n_ens=$ENS_NUM_ANAL,beta_s0=0.25,readin_beta=.false.,s_ens_h=800,s_ens_v=-0.7,generate_ens=.false.,uv_hyb_ens=.true.,jcap_ens=62,
- nlat_ens=96,nlon_ens=192,ANISO_A_EN=.false.,jcap_ens_test=62,oz_univ_static=.true.,readin_localization=.true.,
- write_ens_sprd=.false.,
- $HYBRID_ENSEMBLE
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- /
- &CHEM
-
- /
- &SINGLEOB_TEST
- maginnov=0.1,magoberr=0.1,oneob_type='t',
- oblat=45.,oblon=180.,obpres=1000.,obdattim=${global_hybrid_T126_adate},
- obhourset=0.,
- $SINGLEOB
- /
- &NST
- /
-"
-;;
-
- global_4denvar )
-
-# Define namelist for global hybrid run
-
-export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=5,niter(2)=10,
- niter_no_qc(1)=2,niter_no_qc(2)=0,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- qoption=2,
- gencode=0,factqmin=0.5,factqmax=0.0002,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,l_foto=.false.,
- use_pbl=.false.,use_compress=.true.,nsig_ext=45,gpstop=50.,
- commgpstop=45.,commgpserrinf=1.0,
- use_gfs_nemsio=.false.,lrun_subdirs=.true.,
- use_readin_anl_sfcmask=.true.,
- crtm_coeffs_path='./crtm_coeffs/',
- newpc4pred=.true.,adp_anglebc=.true.,angord=4,passive_bc=.true.,use_edges=.false.,
- diag_precon=.true.,step_start=1.e-3,emiss_bc=.true.,thin4d=.true.,cwoption=3,
- verbose=.false.,imp_physics=11,lupp=.true.,
- binary_diag=.false.,netcdf_diag=.true.,
- lobsdiag_forenkf=.false.,
- nhr_anal=3,6,9,nhr_obsbin=1,
- l4densvar=.true.,ens_nstarthr=3,nhr_assimilation=6,lwrite4danl=.true.,
- optconv=0.05,cao_check=.true.,ta2tb=.false.,
- tzr_qc=1,sfcnst_comb=.true.,
- write_fv3_incr=.true.,incvars_to_zero= 'liq_wat_inc','icmr_inc','rwmr_inc','snmr_inc','grle_inc',
- incvars_zero_strat='sphum_inc','liq_wat_inc','icmr_inc','rwmr_inc','snmr_inc','grle_inc',incvars_efold=5, use_gfs_ncio=.true.,
- $SETUP
- /
- &GRIDOPTS
- JCAP=$JCAP,JCAP_B=$JCAP_B,NLAT=$NLAT,NLON=$LONA,nsig=$LEVS,
- regional=.false.,
- $GRIDOPTS
- /
- &BKGERR
- vs=0.7,
- hzscl=1.7,0.8,0.5,
- hswgt=0.45,0.3,0.25,
- bw=0.0,norsp=4,
- bkgv_flowdep=.true.,bkgv_rewgtfct=1.5,
- bkgv_write=.false.,
- cwcoveqqcov=.false.,
- $BKGVERR
- /
- &ANBKGERR
- anisotropic=.false.,
- $ANBKGERR
- /
- &JCOPTS
- ljcdfi=.false.,alphajc=0.0,ljcpdry=.true.,bamp_jcpdry=5.0e7,
- ljc4tlevs=.true.,
- $JCOPTS
- /
- &STRONGOPTS
- tlnmc_option=3,nstrong=1,nvmodes_keep=8,period_max=6.,period_width=1.5,
-
- baldiag_full=.false.,baldiag_inc=.false.,
- $STRONGOPTS
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.true.,oberrflg=.false.,c_varqc=0.04,
- use_poq7=.true.,qc_noirjaco3_pole=.true.,vqc=.false.,nvqc=.true.,hub_norm=.true.,
- aircraft_t_bc=.true.,biaspredt=1.0e5,upd_aircraft=.true.,cleanup_tail=.true.,
- tcp_width=70.0,tcp_ermax=7.35,
- $OBSQC
- /
- &OBS_INPUT
- dmesh(1)=1450.0,dmesh(2)=1500.0,dmesh(3)=1000.0,dmesh(4)=500.0,time_window_max=3.0,
- $OBSINPUT
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 0.0 0 0
- prepbufr t null t 0.0 0 0
- prepbufr_profl t null t 0.0 0 0
- hdobbufr t null t 0.0 0 0
- prepbufr q null q 0.0 0 0
- prepbufr_profl q null q 0.0 0 0
- hdobbufr q null q 0.0 0 0
- prepbufr pw null pw 0.0 0 0
- prepbufr uv null uv 0.0 0 0
- prepbufr_profl uv null uv 0.0 0 0
- satwndbufr uv null uv 0.0 0 0
- hdobbufr uv null uv 0.0 0 0
- prepbufr spd null spd 0.0 0 0
- hdobbufr spd null spd 0.0 0 0
- prepbufr dw null dw 0.0 0 0
- radarbufr rw null rw 0.0 0 0
- nsstbufr sst nsst sst 0.0 0 0
- gpsrobufr gps_bnd null gps 0.0 0 0
- sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
- hirs3bufr hirs3 n17 hirs3_n17 0.0 1 0
- hirs4bufr hirs4 metop-a hirs4_metop-a 0.0 1 1
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs_aqua 0.0 1 1
- amsuabufr amsua n15 amsua_n15 0.0 1 1
- amsuabufr amsua n18 amsua_n18 0.0 1 1
- amsuabufr amsua metop-a amsua_metop-a 0.0 1 1
- airsbufr amsua aqua amsua_aqua 0.0 1 1
- amsubbufr amsub n17 amsub_n17 0.0 1 1
- mhsbufr mhs n18 mhs_n18 0.0 1 1
- mhsbufr mhs metop-a mhs_metop-a 0.0 1 1
- ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_mid aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_hig aqua amsre_aqua 0.0 1 0
- ssmisbufr ssmis f16 ssmis_f16 0.0 1 0
- ssmisbufr ssmis f17 ssmis_f17 0.0 1 0
- ssmisbufr ssmis f18 ssmis_f18 0.0 1 0
- gsnd1bufr sndrd1 g12 sndrD1_g12 0.0 1 0
- gsnd1bufr sndrd2 g12 sndrD2_g12 0.0 1 0
- gsnd1bufr sndrd3 g12 sndrD3_g12 0.0 1 0
- gsnd1bufr sndrd4 g12 sndrD4_g12 0.0 1 0
- gsnd1bufr sndrd1 g11 sndrD1_g11 0.0 1 0
- gsnd1bufr sndrd2 g11 sndrD2_g11 0.0 1 0
- gsnd1bufr sndrd3 g11 sndrD3_g11 0.0 1 0
- gsnd1bufr sndrd4 g11 sndrD4_g11 0.0 1 0
- gsnd1bufr sndrd1 g13 sndrD1_g13 0.0 1 0
- gsnd1bufr sndrd2 g13 sndrD2_g13 0.0 1 0
- gsnd1bufr sndrd3 g13 sndrD3_g13 0.0 1 0
- gsnd1bufr sndrd4 g13 sndrD4_g13 0.0 1 0
- iasibufr iasi metop-a iasi_metop-a 0.0 1 1
- gomebufr gome metop-a gome_metop-a 0.0 2 0
- omibufr omi aura omi_aura 0.0 2 0
- sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
- hirs4bufr hirs4 n19 hirs4_n19 0.0 1 1
- amsuabufr amsua n19 amsua_n19 0.0 1 1
- mhsbufr mhs n19 mhs_n19 0.0 1 1
- tcvitl tcp null tcp 0.0 0 0
- seviribufr seviri m08 seviri_m08 0.0 1 0
- seviribufr seviri m09 seviri_m09 0.0 1 0
- seviribufr seviri m10 seviri_m10 0.0 1 0
- seviribufr seviri m11 seviri_m11 0.0 1 0
- hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 1
- amsuabufr amsua metop-b amsua_metop-b 0.0 1 1
- mhsbufr mhs metop-b mhs_metop-b 0.0 1 1
- iasibufr iasi metop-b iasi_metop-b 0.0 1 1
- gomebufr gome metop-b gome_metop-b 0.0 2 0
- atmsbufr atms npp atms_npp 0.0 1 1
- atmsbufr atms n20 atms_n20 0.0 1 1
- crisbufr cris npp cris_npp 0.0 1 0
- crisfsbufr cris-fsr npp cris-fsr_npp 0.0 1 0
- crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 1 0
- gsnd1bufr sndrd1 g14 sndrD1_g14 0.0 1 0
- gsnd1bufr sndrd2 g14 sndrD2_g14 0.0 1 0
- gsnd1bufr sndrd3 g14 sndrD3_g14 0.0 1 0
- gsnd1bufr sndrd4 g14 sndrD4_g14 0.0 1 0
- gsnd1bufr sndrd1 g15 sndrD1_g15 0.0 1 0
- gsnd1bufr sndrd2 g15 sndrD2_g15 0.0 1 0
- gsnd1bufr sndrd3 g15 sndrD3_g15 0.0 1 0
- gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 1 0
- oscatbufr uv null uv 0.0 0 0
- mlsbufr mls30 aura mls30_aura 0.0 0 0
- avhambufr avhrr metop-a avhrr3_metop-a 0.0 4 0
- avhpmbufr avhrr n18 avhrr3_n18 0.0 4 0
- avhambufr avhrr metop-b avhrr3_metop-b 0.0 4 0
- avhambufr avhrr metop-c avhrr3_metop-c 0.0 4 0
- avhpmbufr avhrr n19 avhrr3_n19 0.0 4 0
- amsr2bufr amsr2 gcom-w1 amsr2_gcom-w1 0.0 3 0
- gmibufr gmi gpm gmi_gpm 0.0 1 0
- saphirbufr saphir meghat saphir_meghat 0.0 3 0
- ahibufr ahi himawari8 ahi_himawari8 0.0 1 0
- abibufr abi g16 abi_g16 0.0 1 0
- abibufr abi g17 abi_g17 0.0 1 0
- rapidscatbufr uv null uv 0.0 0 0
- ompsnpbufr ompsnp npp ompsnp_npp 0.0 0 0
- ompslpbufr ompslp npp ompslp_npp 0.0 0 0
- ompstcbufr ompstc8 npp ompstc8_npp 0.0 2 0
- ompsnpbufr ompsnp n20 ompsnp_n20 0.0 0 0
- ompstcbufr ompstc8 n20 ompstc8_n20 0.0 2 0
- amsuabufr amsua metop-c amsua_metop-c 0.0 1 1
- mhsbufr mhs metop-c mhs_metop-c 0.0 1 1
- iasibufr iasi metop-c iasi_metop-c 0.0 1 1
- sstviirs viirs-m npp viirs-m_npp 0.0 4 0
- sstviirs viirs-m j1 viirs-m_j1 0.0 4 0
- abibufr abi g18 abi_g18 0.0 1 0
- ahibufr ahi himawari9 ahi_himawari9 0.0 1 0
- atmsbufr atms n21 atms_n21 0.0 1 1
- crisfsbufr cris-fsr n21 cris-fsr_n21 0.0 1 0
- sstviirs viirs-m j2 viirs-m_j2 0.0 4 0
- ompsnpbufr ompsnp n21 ompsnp_n21 0.0 0 0
- ompstcbufr ompstc8 n21 ompstc8_n21 0.0 2 0
- gomebufr gome metop-c gome_metop-c 0.0 2 0
-::
- &SUPEROB_RADAR
- $SUPERRAD
- /
- &LAG_DATA
-
- /
- &HYBRID_ENSEMBLE
- l_hyb_ens=.true.,n_ens=$NMEM_ENKF,beta_s0=0.125,readin_beta=.false.,s_ens_h=800,s_ens_v=-0.8,
- generate_ens=.false.,uv_hyb_ens=.true.,jcap_ens=48,nlat_ens=98,nlon_ens=192,
- ANISO_A_EN=.false.,jcap_ens_test=48,oz_univ_static=.false.,readin_localization=.true.,
- ensemble_path='./ensemble_data/',ens_fast_read=.true.,write_ens_sprd=.false.,
- $HYBRID_ENSEMBLE
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
-
- /
- &CHEM
-
- /
- &NST
- nst_gsi=3,nstinfo=4,zsea1=0,zsea2=0,fac_dtl=1,fac_tsl=1,
- /
- &SINGLEOB_TEST
- maginnov=0.1,magoberr=0.1,oneob_type='t',
- oblat=5.,oblon=180.,obpres=850.,obdattim=2022110900,
- obhourset=0.,
- /
-"
-;;
-
- global_fv3_4denvar_C192 )
-
-# Define namelist for global hybrid run
-
-export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=5,niter(2)=5,
- niter_no_qc(1)=2,niter_no_qc(2)=0,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- qoption=2,
- gencode=82,factqmin=0.5,factqmax=0.0002,deltim=400
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,l_foto=.false.,
- use_pbl=.false.,use_compress=.true.,nsig_ext=56,gpstop=55.,
- use_gfs_nemsio=.false.,lrun_subdirs=.true.,use_readin_anl_sfcmask=.true.,
- crtm_coeffs_path='./crtm_coeffs/',
- newpc4pred=.true.,adp_anglebc=.true.,angord=4,passive_bc=.true.,use_edges=.false.,
- diag_precon=.true.,step_start=1.e-3,emiss_bc=.true.,thin4d=.true.,cwoption=3,
- verbose=.false.,imp_physics=11,lupp=.true.,
- binary_diag=.false.,netcdf_diag=.true.,
- lobsdiag_forenkf=.false.,
- nhr_anal=3,6,9,
- l4densvar=.true.,ens_nstarthr=3,nhr_obsbin=1,nhr_assimilation=6,lwrite4danl=.true.,
- tzr_qc=1,sfcnst_comb=.true.,
- write_fv3_incr=.true.,incvars_to_zero= 'liq_wat_inc','icmr_inc',incvars_zero_strat='sphum_inc','liq_wat_inc','icmr_inc',
- incvars_efold=5,
- use_gfs_ncio=.true.,
- $SETUP
- /
- &GRIDOPTS
- JCAP_B=$JCAP_B,JCAP=$JCAP,NLAT=$NLAT,NLON=$LONA,nsig=$LEVS,
- regional=.false.,
- $GRIDOPTS
- /
- &BKGERR
- vs=0.7,
- hzscl=1.7,0.8,0.5,
- hswgt=0.45,0.3,0.25,
- bw=0.0,norsp=4,
- bkgv_flowdep=.true.,bkgv_rewgtfct=1.5,
- bkgv_write=.false.,
- cwcoveqqcov=.false.,
- $BKGVERR
- /
- &ANBKGERR
- anisotropic=.false.,
- $ANBKGERR
- /
- &JCOPTS
- ljcdfi=.false.,alphajc=0.0,ljcpdry=.true.,bamp_jcpdry=5.0e7,
- ljc4tlevs=.true.,
- $JCOPTS
- /
- &STRONGOPTS
- tlnmc_option=3,nstrong=1,nvmodes_keep=8,period_max=6.,period_width=1.5,
- baldiag_full=.false.,baldiag_inc=.false.,
- $STRONGOPTS
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.true.,oberrflg=.false.,c_varqc=0.04,
- use_poq7=.true.,qc_noirjaco3_pole=.true.,vqc=.false.,
- aircraft_t_bc=.true.,biaspredt=1.0e5,upd_aircraft=.true.,cleanup_tail=.true.
- nvqc=.true.,
- $OBSQC
- /
- &OBS_INPUT
- dmesh(1)=1450.0,dmesh(2)=1500.0,dmesh(3)=1000.0,time_window_max=3.0,
- $OBSINPUT
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 0.0 0 0
- prepbufr t null t 0.0 0 0
- prepbufr_profl t null t 0.0 0 0
- prepbufr q null q 0.0 0 0
- prepbufr_profl q null q 0.0 0 0
- prepbufr pw null pw 0.0 0 0
- prepbufr uv null uv 0.0 0 0
- prepbufr_profl uv null uv 0.0 0 0
- satwndbufr uv null uv 0.0 0 0
- prepbufr spd null spd 0.0 0 0
- prepbufr dw null dw 0.0 0 0
- radarbufr rw null rw 0.0 0 0
- nsstbufr sst nsst sst 0.0 0 0
- gpsrobufr gps_bnd null gps 0.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
- hirs3bufr hirs3 n17 hirs3_n17 0.0 1 0
- hirs4bufr hirs4 metop-a hirs4_metop-a 0.0 1 1
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs_aqua 0.0 1 1
- amsuabufr amsua n15 amsua_n15 0.0 1 1
- amsuabufr amsua n18 amsua_n18 0.0 1 1
- amsuabufr amsua metop-a amsua_metop-a 0.0 1 1
- airsbufr amsua aqua amsua_aqua 0.0 1 1
- amsubbufr amsub n17 amsub_n17 0.0 1 1
- mhsbufr mhs n18 mhs_n18 0.0 1 1
- mhsbufr mhs metop-a mhs_metop-a 0.0 1 1
- ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_mid aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_hig aqua amsre_aqua 0.0 1 0
- ssmisbufr ssmis f16 ssmis_f16 0.0 1 0
- ssmisbufr ssmis f17 ssmis_f17 0.0 1 0
- ssmisbufr ssmis f18 ssmis_f18 0.0 1 0
- gsnd1bufr sndrd1 g12 sndrD1_g12 0.0 1 0
- gsnd1bufr sndrd2 g12 sndrD2_g12 0.0 1 0
- gsnd1bufr sndrd3 g12 sndrD3_g12 0.0 1 0
- gsnd1bufr sndrd4 g12 sndrD4_g12 0.0 1 0
- gsnd1bufr sndrd1 g11 sndrD1_g11 0.0 1 0
- gsnd1bufr sndrd2 g11 sndrD2_g11 0.0 1 0
- gsnd1bufr sndrd3 g11 sndrD3_g11 0.0 1 0
- gsnd1bufr sndrd4 g11 sndrD4_g11 0.0 1 0
- gsnd1bufr sndrd1 g13 sndrD1_g13 0.0 1 0
- gsnd1bufr sndrd2 g13 sndrD2_g13 0.0 1 0
- gsnd1bufr sndrd3 g13 sndrD3_g13 0.0 1 0
- gsnd1bufr sndrd4 g13 sndrD4_g13 0.0 1 0
- iasibufr iasi metop-a iasi_metop-a 0.0 1 1
- gomebufr gome metop-a gome_metop-a 0.0 2 0
- omibufr omi aura omi_aura 0.0 2 0
- sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
- hirs4bufr hirs4 n19 hirs4_n19 0.0 1 1
- amsuabufr amsua n19 amsua_n19 0.0 1 1
- mhsbufr mhs n19 mhs_n19 0.0 1 1
- tcvitl tcp null tcp 0.0 0 0
- seviribufr seviri m08 seviri_m08 0.0 1 0
- seviribufr seviri m09 seviri_m09 0.0 1 0
- seviribufr seviri m10 seviri_m10 0.0 1 0
- seviribufr seviri m11 seviri_m11 0.0 1 0
- hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 1
- amsuabufr amsua metop-b amsua_metop-b 0.0 1 1
- mhsbufr mhs metop-b mhs_metop-b 0.0 1 1
- iasibufr iasi metop-b iasi_metop-b 0.0 1 1
- gomebufr gome metop-b gome_metop-b 0.0 2 0
- atmsbufr atms npp atms_npp 0.0 1 1
- atmsbufr atms n20 atms_n20 0.0 1 1
- crisbufr cris npp cris_npp 0.0 1 0
- crisfsbufr cris-fsr npp cris-fsr_npp 0.0 1 0
- crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 1 0
- gsnd1bufr sndrd1 g14 sndrD1_g14 0.0 1 0
- gsnd1bufr sndrd2 g14 sndrD2_g14 0.0 1 0
- gsnd1bufr sndrd3 g14 sndrD3_g14 0.0 1 0
- gsnd1bufr sndrd4 g14 sndrD4_g14 0.0 1 0
- gsnd1bufr sndrd1 g15 sndrD1_g15 0.0 1 0
- gsnd1bufr sndrd2 g15 sndrD2_g15 0.0 1 0
- gsnd1bufr sndrd3 g15 sndrD3_g15 0.0 1 0
- gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 1 0
- oscatbufr uv null uv 0.0 0 0
- mlsbufr mls30 aura mls30_aura 0.0 0 0
- avhambufr avhrr metop-a avhrr3_metop-a 0.0 1 0
- avhpmbufr avhrr n18 avhrr3_n18 0.0 1 0
- avhambufr avhrr metop-b avhrr3_metop-b 0.0 1 0
- avhpmbufr avhrr n19 avhrr3_n19 0.0 1 0
- amsr2bufr amsr2 gcom-w1 amsr2_gcom-w1 0.0 3 0
- gmibufr gmi gpm gmi_gpm 0.0 3 0
- saphirbufr saphir meghat saphir_meghat 0.0 3 0
- ahibufr ahi himawari8 ahi_himawari8 0.0 1 0
- abibufr abi g16 abi_g16 0.0 1 0
- abibufr abi g17 abi_g17 0.0 1 0
- rapidscatbufr uv null uv 0.0 0 0
- ompsnpbufr ompsnp npp ompsnp_npp 0.0 0 0
- ompstcbufr ompstc8 npp ompstc8_npp 0.0 2 0
- amsuabufr amsua metop-c amsua_metop-c 0.0 1 1
- mhsbufr mhs metop-c mhs_metop-c 0.0 1 1
- iasibufr iasi metop-c iasi_metop-c 0.0 1 1
- ompslpbufr ompslp npp ompslp_npp 0.0 1 1
- abibufr abi g18 abi_g18 0.0 1 0
- ahibufr ahi himawari9 ahi_himawari9 0.0 1 0
- atmsbufr atms n21 atms_n21 0.0 1 1
- crisfsbufr cris-fsr n21 cris-fsr_n21 0.0 1 0
- sstviirs viirs-m j2 viirs-m_j2 0.0 4 0
- ompsnpbufr ompsnp n21 ompsnp_n21 0.0 0 0
- ompstcbufr ompstc8 n21 ompstc8_n21 0.0 2 0
- gomebufr gome metop-c gome_metop-c 0.0 2 0
-::
- &SUPEROB_RADAR
- $SUPERRAD
- /
- &LAG_DATA
- $LAGDATA
- /
- &HYBRID_ENSEMBLE
- l_hyb_ens=.true.,n_ens=20,beta_s0=0.125,readin_beta=.false.,s_ens_h=800,s_ens_v=-0.8,generate_ens=.false.,uv_hyb_ens=.true.,jcap_ens=190,
- nlat_ens=194,nlon_ens=384,aniso_a_en=.false.,jcap_ens_test=62,oz_univ_static=.false.,readin_localization=.true.,ensemble_path='./ensemble_data/',
- ens_fast_read=.true.,write_ens_sprd=.false.,
- $HYBRID_ENSEMBLE
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- /
- &CHEM
-
- /
- &SINGLEOB_TEST
- maginnov=0.1,magoberr=0.1,oneob_type='t',
- oblat=45.,oblon=180.,obpres=1000.,obdattim=${global_4denvar_T670_adate},
- obhourset=0.,
- $SINGLEOB
- /
- &NST
- nst_gsi=3,nstinfo=4,fac_dtl=1,fac_tsl=1,zsea1=0,zsea2=0,
- $NST
- /
-"
-;;
-
- RTMA)
-
-# Define namelist for RTMA runs
-
-export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=10,niter(2)=10,
- write_diag(1)=.true.,write_diag(2)=.true.,write_diag(3)=.true.,
- gencode=78,qoption=1,tsensible=.true.
- factqmin=1.0,factqmax=1.0,factv=0.0,factcldch=0.0,factw10m=1.0,deltim=$DELTIM,
+ miter=2,niter(1)=5,niter(2)=5,
+ write_diag(1)=.true.,write_diag(2)=.true.,write_diag(3)=.true.,
+ gencode=78,qoption=1,tsensible=.true.
+ factqmin=1.0,factqmax=1.0,factv=0.0,factcldch=0.0,factw10m=1.0,deltim=$DELTIM,
iguess=-1,
oneobtest=.false.,retrieval=.false.,
diag_rad=.false.,diag_pcp=.false.,diag_ozone=.false.,diag_aero=.false.,
@@ -1016,394 +242,100 @@ export gsi_namelist="
/
&GRIDOPTS
JCAP=$JCAP,JCAP_B=$JCAP_B,NLAT=$NLAT,NLON=$LONA,nsig=$LEVS,
- wrf_nmm_regional=.false.,wrf_mass_regional=.false.,twodvar_regional=.true.,
- diagnostic_reg=.false.,
- filled_grid=.false.,half_grid=.true.,netcdf=.false.,
- /
- &BKGERR
- hzscl=1.414,1.000,0.707,
- vs=0.5,bw=0.0,
- /
- &ANBKGERR
- anisotropic=.true.,an_vs=0.5,ngauss=1,
- an_flen_u=-5.,an_flen_t=3.,an_flen_z=-200.,
- ifilt_ord=2,npass=3,normal=-200,grid_ratio=1.,nord_f2a=4,
- rtma_subdomain_option=.true.,triad4=.true.,nsmooth=0,nsmooth_shapiro=0,lreadnorm=.true.,
- /
- &JCOPTS
- /
- &STRONGOPTS
- nstrong=1,nvmodes_keep=20,period_max=3.,
- baldiag_full=.true.,baldiag_inc=.true.,
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.true.,c_varqc=0.02,vadfile='prepbufr',hilbert_curve=.true.,
- buddycheck_t=.false.,buddydiag_save=.false.,oberrflg=.true.,njqc=.true.,vqc=.false.,
- $OBSQC
- /
- &OBS_INPUT
- dmesh(1)=60.0,dmesh(2)=60.0,dmesh(3)=60.0,dmesh(4)=60.0,time_window_max=3.0,
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 1.0 0 0
- prepbufr t null t 1.0 0 0
- prepbufr q null q 1.0 0 0
- prepbufr uv null uv 1.0 0 0
- satwndbufr uv null uv 1.0 0 0
- prepbufr spd null spd 1.0 0 0
- prepbufr wspd10m null wspd10m 1.0 0 0
- satwnd wspd10m null wspd10m 1.0 0 0
- prepbufr uwnd10m null uwnd10m 1.0 0 0
- satwnd uwnd10m null uwnd10m 1.0 0 0
- prepbufr vwnd10m null vwnd10m 1.0 0 0
- satwnd vwnd10m null vwnd10m 1.0 0 0
- prepbufr gust null gust 1.0 0 0
- prepbufr vis null vis 1.0 0 0
- prepbufr td2m null td2m 1.0 0 0
- mxtmdat mxtm null mxtm 1.0 0 0
- mitmdat mitm null mitm 1.0 0 0
- prepbufr mxtm null mxtm 1.0 0 0
- prepbufr mitm null mitm 1.0 0 0
- prepbufr pmsl null pmsl 1.0 0 0
- prepbufr howv null howv 1.0 0 0
- satmar howv null howv 1.0 0 0
- prepbufr tcamt null tcamt 1.0 0 0
- goessky tcamt null tcamt 1.0 0 0
- prepbufr cldch null cldch 1.0 0 0
-::
- &SUPEROB_RADAR
- /
- &LAG_DATA
- /
- &HYBRID_ENSEMBLE
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- l_closeobs=.true.
- /
- &CHEM
- /
- &SINGLEOB_TEST
- maginnov=0.1,magoberr=0.1,oneob_type='t',
- oblat=36.,oblon=260.,obpres=1000.,obdattim=${adate},
- obhourset=0.,
- /
- &NST
- /
-"
-;;
-
- arw_binary)
-
-# Define namelist for arw binary run
-
-export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=50,niter(2)=50,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- gencode=78,qoption=2,
- factqmin=0.0,factqmax=0.0,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,
- nhr_assimilation=3,l_foto=.false.,
- use_pbl=.false.,use_compress=.false.,nsig_ext=13,gpstop=30.,
- lrun_subdirs=.true.,
- $SETUP
- /
- &GRIDOPTS
- JCAP=$JCAP,NLAT=$NLAT,NLON=$LONA,nsig=$LEVS,
- wrf_nmm_regional=.false.,wrf_mass_regional=.true.,diagnostic_reg=.false.,
- filled_grid=.false.,half_grid=.true.,netcdf=$NETCDF,
- /
- &BKGERR
- hzscl=0.373,0.746,1.50,
- vs=1.0,bw=0.,fstat=.true.,
- /
- &ANBKGERR
- anisotropic=.false.,an_vs=1.0,ngauss=1,
- an_flen_u=-5.,an_flen_t=3.,an_flen_z=-200.,
- ifilt_ord=2,npass=3,normal=-200,grid_ratio=4.,nord_f2a=4,
- /
- &JCOPTS
- /
- &STRONGOPTS
- nstrong=0,nvmodes_keep=20,period_max=3.,
- baldiag_full=.true.,baldiag_inc=.true.,
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.true.,c_varqc=0.02,vadfile='prepbufr',oberrflg=.false.,njqc=.false.,vqc=.true.,
- /
- &OBS_INPUT
- dmesh(1)=120.0,dmesh(2)=60.0,dmesh(3)=60.0,dmesh(4)=60.0,dmesh(5)=120,time_window_max=1.5,
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 1.0 0 0
- prepbufr t null t 1.0 0 0
- prepbufr q null q 1.0 0 0
- prepbufr uv null uv 1.0 0 0
- satwndbufr uv null uv 1.0 0 0
- prepbufr spd null spd 1.0 0 0
- radarbufr rw null l3rw 1.0 0 0
- l2rwbufr rw null l2rw 1.0 0 0
- prepbufr dw null dw 1.0 0 0
- prepbufr sst null sst 1.0 0 0
- prepbufr pw null pw 1.0 0 0
- gpsrobufr $gps_dtype null gps 1.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 1.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 1.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 1.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 1.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 1.0 0 0
- omi omi aura omi_aura 1.0 6 0
- hirs2bufr hirs2 n14 hirs2_n14 6.0 1 1
- hirs3bufr hirs3 n16 hirs3_n16 0.0 1 1
- hirs3bufr hirs3 n17 hirs3_n17 6.0 1 1
- hirs4bufr hirs4 n18 hirs4_n18 0.0 1 1
- hirs4bufr hirs4 metop-a hirs4_metop-a 6.0 1 1
- gsndrbufr sndr g11 sndr_g11 0.0 1 0
- gsndrbufr sndr g12 sndr_g12 0.0 1 0
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs_aqua 20.0 1 1
- msubufr msu n14 msu_n14 2.0 2 1
- amsuabufr amsua n15 amsua_n15 10.0 2 1
- amsuabufr amsua n16 amsua_n16 0.0 2 1
- amsuabufr amsua n17 amsua_n17 0.0 2 1
- amsuabufr amsua n18 amsua_n18 10.0 2 1
- amsuabufr amsua metop-a amsua_metop-a 10.0 2 1
- airsbufr amsua aqua amsua_aqua 5.0 2 1
- amsubbufr amsub n15 amsub_n15 3.0 3 1
- amsubbufr amsub n16 amsub_n16 3.0 3 1
- amsubbufr amsub n17 amsub_n17 3.0 3 1
- mhsbufr mhs n18 mhs_n18 3.0 3 1
- mhsbufr mhs metop-a mhs_metop-a 3.0 3 1
- ssmitbufr ssmi f13 ssmi_f13 0.0 4 0
- ssmitbufr ssmi f15 ssmi_f15 0.0 4 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 4 1
- amsrebufr amsre_mid aqua amsre_aqua 0.0 4 1
- amsrebufr amsre_hig aqua amsre_aqua 0.0 4 1
- ssmisbufr ssmis f16 ssmis_f16 0.0 4 1
- gsnd1bufr sndrd1 g12 sndrD1_g12 1.5 5 0
- gsnd1bufr sndrd2 g12 sndrD2_g12 1.5 5 0
- gsnd1bufr sndrd3 g12 sndrD3_g12 1.5 5 0
- gsnd1bufr sndrd4 g12 sndrD4_g12 1.5 5 0
- gsnd1bufr sndrd1 g11 sndrD1_g11 1.5 5 0
- gsnd1bufr sndrd2 g11 sndrD2_g11 1.5 5 0
- gsnd1bufr sndrd3 g11 sndrD3_g11 1.5 5 0
- gsnd1bufr sndrd4 g11 sndrD4_g11 1.5 5 0
- gsnd1bufr sndrd1 g13 sndrD1_g13 1.5 5 0
- gsnd1bufr sndrd2 g13 sndrD2_g13 1.5 5 0
- gsnd1bufr sndrd3 g13 sndrD3_g13 1.5 5 0
- gsnd1bufr sndrd4 g13 sndrD4_g13 1.5 5 0
- iasibufr iasi metop-a iasi_metop-a 20.0 1 1
- gomebufr gome metop-a gome_metop-a 1.0 6 0
- mlsbufr mls30 aura mls30_aura 1.0 0 0
- oscatbufr uv null uv 1.0 0 0
- ompsnpbufr ompsnp npp ompsnp_npp 1.0 0 0
- ompstcbufr ompstc8 npp ompstc8_npp 1.0 6 0
-::
- &SUPEROB_RADAR
- del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000.,
- l2superob_only=.false.,
- /
- &LAG_DATA
- /
- &HYBRID_ENSEMBLE
- l_hyb_ens=${HYBENS_REGIONAL},
- n_ens=${ENSEMBLE_SIZE_REGIONAL},
- uv_hyb_ens=${HYBENS_UV_REGIONAL},
- beta_s0=${BETA_S0_REGIONAL},
- readin_beta=.false.,
- s_ens_h=${HYBENS_HOR_SCALE_REGIONAL},
- s_ens_v=${HYBENS_VER_SCALE_REGIONAL},
- generate_ens=${GENERATE_ENS_REGIONAL},
- aniso_a_en=${HYBENS_ANISO_REGIONAL},
- nlon_ens=${NLON_ENS_REGIONAL},
- nlat_ens=${NLAT_ENS_REGIONAL},
- jcap_ens=${JCAP_ENS_REGIONAL},
- jcap_ens_test=${JCAP_ENS_TEST_REGIONAL},
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- /
- &CHEM
- /
- &SINGLEOB_TEST
- maginnov=0.1,magoberr=0.1,oneob_type='t',
- oblat=45.,oblon=270.,obpres=850.,obdattim=${adate},
- obhourset=0.,
- /
- &NST
- /
-"
-;;
-
- arw_netcdf)
-
-# Define namelist for arw netcdf run
-
-export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=50,niter(2)=50,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- gencode=78,qoption=2,
- factqmin=0.0,factqmax=0.0,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,
- nhr_assimilation=3,l_foto=.false.,
- use_pbl=.false.,use_compress=.false.,nsig_ext=13,gpstop=30.,
- lrun_subdirs=.true.,
- $SETUP
- /
- &GRIDOPTS
- JCAP=$JCAP,JCAP_B=$JCAP_B,NLAT=$NLAT,NLON=$LONA,nsig=$LEVS,
- wrf_nmm_regional=.false.,wrf_mass_regional=.true.,diagnostic_reg=.false.,
- filled_grid=.false.,half_grid=.true.,netcdf=$NETCDF,
+ wrf_nmm_regional=.false.,wrf_mass_regional=.false.,twodvar_regional=.true.,
+ diagnostic_reg=.false.,
+ filled_grid=.false.,half_grid=.true.,netcdf=.false.,
/
&BKGERR
- hzscl=0.373,0.746,1.50,
- vs=1.0,bw=0.,fstat=.true.,
+ hzscl=1.414,1.000,0.707,
+ vs=0.5,bw=0.0,
/
&ANBKGERR
- anisotropic=.false.,an_vs=1.0,ngauss=1,
+ anisotropic=.true.,an_vs=0.5,ngauss=1,
an_flen_u=-5.,an_flen_t=3.,an_flen_z=-200.,
- ifilt_ord=2,npass=3,normal=-200,grid_ratio=4.,nord_f2a=4,
+ ifilt_ord=2,npass=3,normal=-200,grid_ratio=1.,nord_f2a=4,
+ rtma_subdomain_option=.true.,triad4=.true.,nsmooth=0,nsmooth_shapiro=0,lreadnorm=.true.,
/
&JCOPTS
/
&STRONGOPTS
- nstrong=0,nvmodes_keep=20,period_max=3.,
+ nstrong=1,nvmodes_keep=20,period_max=3.,
baldiag_full=.true.,baldiag_inc=.true.,
/
&OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.true.,c_varqc=0.02,vadfile='prepbufr',oberrflg=.false.,njqc=.false.,vqc=.true.,
+ dfact=0.75,dfact1=3.0,noiqc=.true.,c_varqc=0.02,vadfile='prepbufr',hilbert_curve=.true.,
+ buddycheck_t=.false.,buddydiag_save=.false.,oberrflg=.true.,njqc=.true.,vqc=.false.,
+ $OBSQC
/
&OBS_INPUT
- dmesh(1)=120.0,dmesh(2)=60.0,dmesh(3)=60.0,dmesh(4)=60.0,dmesh(5)=120,time_window_max=1.5,
+ dmesh(1)=60.0,dmesh(2)=60.0,dmesh(3)=60.0,dmesh(4)=60.0,time_window_max=3.0,
/
OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 1.0 0 0
- prepbufr t null t 1.0 0 0
- prepbufr q null q 1.0 0 0
- prepbufr uv null uv 1.0 0 0
- satwndbufr uv null uv 1.0 0 0
- prepbufr spd null spd 1.0 0 0
- radarbufr rw null l3rw 1.0 0 0
- l2rwbufr rw null l2rw 1.0 0 0
- prepbufr dw null dw 1.0 0 0
- prepbufr sst null sst 1.0 0 0
- prepbufr pw null pw 1.0 0 0
- gpsrobufr $gps_dtype null gps 1.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 1.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 1.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 1.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 1.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 1.0 0 0
- omi omi aura omi_aura 1.0 6 0
- hirs2bufr hirs2 n14 hirs2_n14 6.0 1 1
- hirs3bufr hirs3 n16 hirs3_n16 0.0 1 1
- hirs3bufr hirs3 n17 hirs3_n17 6.0 1 1
- hirs4bufr hirs4 n18 hirs4_n18 0.0 1 1
- hirs4bufr hirs4 metop-a hirs4_metop-a 6.0 1 1
- gsndrbufr sndr g11 sndr_g11 0.0 1 0
- gsndrbufr sndr g12 sndr_g12 0.0 1 0
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs_aqua 20.0 1 1
- msubufr msu n14 msu_n14 2.0 2 1
- amsuabufr amsua n15 amsua_n15 10.0 2 1
- amsuabufr amsua n16 amsua_n16 0.0 2 1
- amsuabufr amsua n17 amsua_n17 0.0 2 1
- amsuabufr amsua n18 amsua_n18 10.0 2 1
- amsuabufr amsua metop-a amsua_metop-a 10.0 2 1
- airsbufr amsua aqua amsua_aqua 5.0 2 1
- amsubbufr amsub n15 amsub_n15 3.0 3 1
- amsubbufr amsub n16 amsub_n16 3.0 3 1
- amsubbufr amsub n17 amsub_n17 3.0 3 1
- mhsbufr mhs n18 mhs_n18 3.0 3 1
- mhsbufr mhs metop-a mhs_metop-a 3.0 3 1
- ssmitbufr ssmi f13 ssmi_f13 0.0 4 0
- ssmitbufr ssmi f15 ssmi_f15 0.0 4 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 4 1
- amsrebufr amsre_mid aqua amsre_aqua 0.0 4 1
- amsrebufr amsre_hig aqua amsre_aqua 0.0 4 1
- ssmisbufr ssmis f16 ssmis_f16 0.0 4 1
- gsnd1bufr sndrd1 g12 sndrD1_g12 1.5 5 0
- gsnd1bufr sndrd2 g12 sndrD2_g12 1.5 5 0
- gsnd1bufr sndrd3 g12 sndrD3_g12 1.5 5 0
- gsnd1bufr sndrd4 g12 sndrD4_g12 1.5 5 0
- gsnd1bufr sndrd1 g11 sndrD1_g11 1.5 5 0
- gsnd1bufr sndrd2 g11 sndrD2_g11 1.5 5 0
- gsnd1bufr sndrd3 g11 sndrD3_g11 1.5 5 0
- gsnd1bufr sndrd4 g11 sndrD4_g11 1.5 5 0
- gsnd1bufr sndrd1 g13 sndrD1_g13 1.5 5 0
- gsnd1bufr sndrd2 g13 sndrD2_g13 1.5 5 0
- gsnd1bufr sndrd3 g13 sndrD3_g13 1.5 5 0
- gsnd1bufr sndrd4 g13 sndrD4_g13 1.5 5 0
- iasibufr iasi metop-a iasi_metop-a 20.0 1 1
- gomebufr gome metop-a gome_metop-a 1.0 6 0
- mlsbufr mls30 aura mls30_aura 1.0 0 0
- oscatbufr uv null uv 1.0 0 0
- ompsnpbufr ompsnp npp ompsnp_npp 1.0 0 0
- ompstcbufr ompstc8 npp ompstc8_npp 1.0 6 0
+! dfile dtype dplat dsis dval dthin dsfcalc
+ prepbufr ps null ps 1.0 0 0
+ prepbufr t null t 1.0 0 0
+ prepbufr q null q 1.0 0 0
+ prepbufr uv null uv 1.0 0 0
+ satwndbufr uv null uv 1.0 0 0
+ prepbufr spd null spd 1.0 0 0
+ prepbufr wspd10m null wspd10m 1.0 0 0
+ satwnd wspd10m null wspd10m 1.0 0 0
+ prepbufr uwnd10m null uwnd10m 1.0 0 0
+ satwnd uwnd10m null uwnd10m 1.0 0 0
+ prepbufr vwnd10m null vwnd10m 1.0 0 0
+ satwnd vwnd10m null vwnd10m 1.0 0 0
+ prepbufr gust null gust 1.0 0 0
+ prepbufr vis null vis 1.0 0 0
+ prepbufr td2m null td2m 1.0 0 0
+ mxtmdat mxtm null mxtm 1.0 0 0
+ mitmdat mitm null mitm 1.0 0 0
+ prepbufr mxtm null mxtm 1.0 0 0
+ prepbufr mitm null mitm 1.0 0 0
+ prepbufr pmsl null pmsl 1.0 0 0
+ prepbufr howv null howv 1.0 0 0
+ satmar howv null howv 1.0 0 0
+ prepbufr tcamt null tcamt 1.0 0 0
+ goessky tcamt null tcamt 1.0 0 0
+ prepbufr cldch null cldch 1.0 0 0
::
&SUPEROB_RADAR
- del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000.,
- l2superob_only=.false.,
/
&LAG_DATA
/
&HYBRID_ENSEMBLE
- l_hyb_ens=${HYBENS_REGIONAL},
- n_ens=${ENSEMBLE_SIZE_REGIONAL},
- uv_hyb_ens=${HYBENS_UV_REGIONAL},
- beta_s0=${BETA_S0_REGIONAL},
- readin_beta=.false.,
- s_ens_h=${HYBENS_HOR_SCALE_REGIONAL},
- s_ens_v=${HYBENS_VER_SCALE_REGIONAL},
- generate_ens=${GENERATE_ENS_REGIONAL},
- aniso_a_en=${HYBENS_ANISO_REGIONAL},
- nlon_ens=${NLON_ENS_REGIONAL},
- nlat_ens=${NLAT_ENS_REGIONAL},
- jcap_ens=${JCAP_ENS_REGIONAL},
- jcap_ens_test=${JCAP_ENS_TEST_REGIONAL},
/
&RAPIDREFRESH_CLDSURF
dfi_radar_latent_heat_time_period=30.0,
+ l_closeobs=.true.
/
&CHEM
/
&SINGLEOB_TEST
maginnov=0.1,magoberr=0.1,oneob_type='t',
- oblat=45.,oblon=270.,obpres=850.,obdattim=${adate},
+ oblat=36.,oblon=260.,obpres=1000.,obdattim=${adate},
obhourset=0.,
/
&NST
/
"
;;
-
- rrfs_3denvar_glbens)
+ rrfs_3denvar_rdasens)
# Define namelist for rrfs 3d hybrid envar run with global ensembles
export gsi_namelist="
&SETUP
- miter=2,niter(1)=25,niter(2)=25,
+ miter=2,niter(1)=5,niter(2)=5,
write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- qoption=2,print_obs_para=.true.,diag_radardbz=.false.,
- if_model_dbz=.false., static_gsi_nopcp_dbz=0.0,
+ qoption=2,print_obs_para=.true.,diag_fed=.true.,diag_radardbz=.false.,
+ if_model_dbz=.true.,if_model_fed=.true.,static_gsi_nopcp_dbz=0.0,if_use_w_vr=.false.,
rmesh_dbz=4.0,rmesh_vr=4.0,zmesh_dbz=1000.0,zmesh_vr=1000.0,
- missing_to_nopcp=.false.,radar_no_thinning=.true.,
+ inflate_dbz_obserr=.true.,missing_to_nopcp=.false.,radar_no_thinning=.true.,
gencode=78,factqmin=0.0,factqmax=0.0,
- iguess=-1,
+ iguess=-1,crtm_coeffs_path='./',
lread_obs_save=.false.,lread_obs_skip=.false.,
+ ens_nstarthr=01,
oneobtest=.false.,retrieval=.false.,
nhr_assimilation=3,l_foto=.false.,
use_pbl=.false.,use_prepb_satwnd=.false.,
@@ -1412,8 +344,10 @@ export gsi_namelist="
diag_precon=.true.,step_start=1.e-3,
l4densvar=.false.,nhr_obsbin=3,
use_gfs_nemsio=.false.,use_gfs_ncio=.true.,reset_bad_radbc=.true.,
- netcdf_diag=.false.,binary_diag=.true.,
+ netcdf_diag=.true.,binary_diag=.false.,
l_obsprvdiag=.false.,
+ lwrite_peakwt=.true.,
+ innov_use_model_fed=.true.,
/
&GRIDOPTS
fv3_regional=.true.,grid_ratio_fv3_regional=2.0,nvege_type=20,
@@ -1441,7 +375,9 @@ export gsi_namelist="
/
OBS_INPUT::
! dfile dtype dplat dsis dval dthin dsfcalc
+ pm25bufr pm2_5 null TEOM 1.0 0 0
dbzobs.nc dbz null dbz 1.0 0 0
+ fedobs.nc fed null fed 1.0 0 0
prepbufr ps null ps 1.0 0 0
prepbufr t null t 1.0 0 0
prepbufr q null q 1.0 0 0
@@ -1472,12 +408,14 @@ OBS_INPUT::
amsuabufr amsua n19 amsua_n19 0.0 2 0
amsuabufr amsua metop-a amsua_metop-a 0.0 2 0
amsuabufr amsua metop-b amsua_metop-b 0.0 2 0
+ amsuabufr amsua metop-c amsua_metop-c 0.0 2 0
airsbufr amsua aqua amsua_aqua 0.0 2 0
amsubbufr amsub n17 amsub_n17 0.0 1 0
mhsbufr mhs n18 mhs_n18 0.0 2 0
mhsbufr mhs n19 mhs_n19 0.0 2 0
mhsbufr mhs metop-a mhs_metop-a 0.0 2 0
mhsbufr mhs metop-b mhs_metop-b 0.0 2 0
+ mhsbufr mhs metop-c mhs_metop-c 0.0 2 0
ssmitbufr ssmi f13 ssmi_f13 0.0 2 0
ssmitbufr ssmi f14 ssmi_f14 0.0 2 0
ssmitbufr ssmi f15 ssmi_f15 0.0 2 0
@@ -1506,11 +444,23 @@ OBS_INPUT::
gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 2 0
iasibufr iasi metop-a iasi_metop-a 0.0 2 0
gomebufr gome metop-a gome_metop-a 0.0 2 0
+ omibufr omi aura omi_aura 0.0 2 0
+ sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
+ tcvitl tcp null tcp 0.0 0 0
+ seviribufr seviri m08 seviri_m08 0.0 2 0
+ seviribufr seviri m09 seviri_m09 0.0 2 0
+ seviribufr seviri m10 seviri_m10 0.0 2 0
+ seviribufr seviri m11 seviri_m11 0.0 2 0
+ iasibufr iasi metop-b iasi_metop-b 0.0 2 0
+ iasibufr iasi metop-c iasi_metop-c 0.0 2 0
+ gomebufr gome metop-b gome_metop-b 0.0 2 0
atmsbufr atms npp atms_npp 0.0 2 0
atmsbufr atms n20 atms_n20 0.0 2 0
+ atmsbufr atms n21 atms_n21 0.0 2 0
crisbufr cris npp cris_npp 0.0 2 0
crisfsbufr cris-fsr npp cris-fsr_npp 0.0 2 0
crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 2 0
+ crisfsbufr cris-fsr n21 cris-fsr_n21 0.0 2 0
abibufr abi g16 abi_g16 0.0 2 0
mlsbufr mls30 aura mls30_aura 0.0 0 0
oscatbufr uv null uv 0.0 0 0
@@ -1519,6 +469,7 @@ OBS_INPUT::
refInGSI rad_ref null rad_ref 1.0 0 0
lghtInGSI lghtn null lghtn 1.0 0 0
larcInGSI larccld null larccld 1.0 0 0
+ abibufr abi g18 abi_g18 0.0 2 0
::
&SUPEROB_RADAR
del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000., l2superob_only=.false.,
@@ -1531,17 +482,30 @@ OBS_INPUT::
q_hyb_ens=.false.,
aniso_a_en=.false.,generate_ens=.false.,
n_ens=${nummem},
- beta_s0=0.15,s_ens_h=110,s_ens_v=3,
- regional_ensemble_option=1,
+ l_both_fv3sar_gfs_ens=.false.,n_ens_gfs=0,n_ens_fv3sar=30,
+ weight_ens_gfs=1.0,weight_ens_fv3sar=1.0,
+ beta_s0=0.15,s_ens_h=328.632,82.1580,4.10790,4.10790,82.1580,s_ens_v=3,3,-0.30125,-0.30125,0.0,
+ regional_ensemble_option=5,
pseudo_hybens = .false.,
- grid_ratio_ens = 3,
+ grid_ratio_ens = 1,
l_ens_in_diff_time=.true.,
ensemble_path='',
i_en_perts_io=1,
jcap_ens=574,
fv3sar_bg_opt=0,
- readin_localization=.true.,
- ens_fast_read=.false.,
+ readin_localization=.false.,
+ parallelization_over_ensmembers=.false.,
+ nsclgrp=2,l_timloc_opt=.false.,ngvarloc=2,naensloc=5,
+ r_ensloccov4tim=1.0,r_ensloccov4var=0.05,r_ensloccov4scl=1.0,
+ global_spectral_filter_sd=.false.,assign_vdl_nml=.false.,vdl_scale=0,
+ vloc_varlist(1,1)='sf ',vloc_varlist(2,1)='w ',vloc_varlist(3,1)='sf ',vloc_varlist(4,1)='w ',
+ vloc_varlist(1,2)='vp ',vloc_varlist(2,2)='qr ',vloc_varlist(3,2)='vp ',vloc_varlist(4,2)='qr ',
+ vloc_varlist(1,3)='ps ',vloc_varlist(2,3)='qs ',vloc_varlist(3,3)='ps ',vloc_varlist(4,3)='qs ',
+ vloc_varlist(1,4)='t ',vloc_varlist(2,4)='qi ',vloc_varlist(3,4)='t ',vloc_varlist(4,4)='qi ',
+ vloc_varlist(1,5)='q ',vloc_varlist(2,5)='qg ',vloc_varlist(3,5)='q ',vloc_varlist(4,5)='qg ',
+ vloc_varlist(1,6)='sst',vloc_varlist(2,6)='ql ',vloc_varlist(3,6)='sst',vloc_varlist(4,6)='ql ',
+ vloc_varlist(1,7)='stl',vloc_varlist(2,7)='dbz',vloc_varlist(3,7)='stl',vloc_varlist(4,7)='dbz',
+ vloc_varlist(1,8)='sti',vloc_varlist(2,8)='aaa',vloc_varlist(3,8)='sti',vloc_varlist(4,8)='aaa',
/
&RAPIDREFRESH_CLDSURF
dfi_radar_latent_heat_time_period=20.0,
@@ -1581,6 +545,8 @@ OBS_INPUT::
i_gsdqc=2,
/
&CHEM
+ laeroana_fv3smoke=.false.,
+ berror_fv3_cmaq_regional=.false.,
/
&NST
/
@@ -1591,255 +557,49 @@ OBS_INPUT::
/
"
;;
- netcdf_fv3_regional)
-
-# Define namelist for netcdf fv3 run
+ hafs_envar)
+# Define namelist for hafs 3denvar run with global ensembles
export gsi_namelist="
&SETUP
- miter=2,niter(1)=50,niter(2)=50,niter_no_qc(1)=20,
+ miter=2,niter(1)=5,niter(2)=5,
+ niter_no_qc(1)=2,niter_no_qc(2)=0,
write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
qoption=2,
- factqmin=0.0,factqmax=0.0,deltim=$DELTIM,
+ gencode=78,deltim=1200,
+ factqmin=0.0,factqmax=0.0,
iguess=-1,
- newpc4pred=.true., adp_anglebc=.true., angord=4,
- diag_precon=.true., step_start=1.e-3,
- nhr_assimilation=3,l_foto=.false.,
- use_pbl=.false.,use_compress=.false.,gpstop=30.,
+ aircraft_recon=.true.,
+ oneobtest=.false.,retrieval=.false.,l_foto=.false.,
+ nhr_assimilation=6,
+ use_pbl=.true.,use_compress=.false.,nsig_ext=14,gpstop=50.,
+ use_gfs_nemsio=.false.,use_gfs_ncio=.true.,
+ print_diag_pcg=.true.,l2rwthin=.false.,hurricane_radar=.true.,
+ use_gfs_ozone=.false.,l4densvar=${l4densvar},nhr_obsbin=${nhr_obsbin},
lrun_subdirs=.true.,
- $SETUP
- /
- &GRIDOPTS
- fv3_regional=.true.,grid_ratio_fv3_regional=3.0,
- /
- &BKGERR
- hzscl=0.373,0.746,1.50,
- vs=0.6,bw=0.,fstat=.false.,
- /
- &ANBKGERR
- anisotropic=.false.,
- /
- &JCOPTS
- /
- &STRONGOPTS
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.true.,c_varqc=0.02,
- vadfile='prepbufr',oberrflg=.false.,njqc=.false.,vqc=.true.,
- /
- &OBS_INPUT
- dmesh(1)=120.0,dmesh(2)=60.0,dmesh(3)=60.0,dmesh(4)=60.0,dmesh(5)=120,time_window_max=1.5,ext_sonde=.true.,
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 0.0 0 0
- prepbufr t null t 0.0 0 0
- prepbufr q null q 0.0 0 0
- prepbufr pw null pw 0.0 0 0
- prepbufr uv null uv 0.0 0 0
- prepbufr spd null spd 0.0 0 0
- prepbufr dw null dw 0.0 0 0
- radarbufr rw null rw 0.0 0 0
- prepbufr sst null sst 0.0 0 0
- gpsrobufr gps_bnd null gps_bnd 0.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
- hirs2bufr hirs2 n14 hirs2_n14 0.0 1 0
- hirs3bufr hirs3 n16 hirs3_n16 0.0 1 0
- hirs3bufr hirs3 n17 hirs3_n17 0.0 1 0
- hirs4bufr hirs4 n18 hirs4_n18 0.0 1 0
- hirs4bufr hirs4 metop-a hirs4_metop-a 0.0 1 0
- hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 0
- gsndrbufr sndr g11 sndr_g11 0.0 1 0
- gsndrbufr sndr g12 sndr_g12 0.0 1 0
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs281_aqua 0.0 1 0
- msubufr msu n14 msu_n14 0.0 1 0
- amsuabufr amsua n15 amsua_n15 0.0 1 0
- amsuabufr amsua n16 amsua_n16 0.0 1 0
- amsuabufr amsua n17 amsua_n17 0.0 1 0
- amsuabufr amsua n18 amsua_n18 0.0 1 0
- amsuabufr amsua metop-a amsua_metop-a 0.0 1 0
- amsuabufr amsua metop-b amsua_metop-b 0.0 1 0
- airsbufr amsua aqua amsua_aqua 0.0 1 0
- amsubbufr amsub n15 amsub_n15 0.0 1 0
- amsubbufr amsub n16 amsub_n16 0.0 1 0
- amsubbufr amsub n17 amsub_n17 0.0 1 0
- mhsbufr mhs n18 mhs_n18 0.0 1 0
- mhsbufr mhs metop-a mhs_metop-a 0.0 1 0
- mhsbufr mhs metop-b mhs_metop-b 0.0 1 0
- ssmitbufr ssmi f13 ssmi_f13 0.0 1 0
- ssmitbufr ssmi f14 ssmi_f14 0.0 1 0
- ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_mid aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_hig aqua amsre_aqua 0.0 1 0
- ssmisbufr ssmis f16 ssmis_f16 0.0 1 0
- iasibufr iasi metop-a iasi_metop-a 0.0 1 0
- gomebufr gome metop-a gome_metop-a 0.0 1 0
- iasibufr iasi metop-b iasi_metop-b 0.0 1 0
- omibufr omi aura omi_aura 0.0 1 0
- sbuvbufr sbuv2 n19 sbuv8_n19 0.0 1 0
- hirs4bufr hirs4 n19 hirs4_n19 0.0 1 0
- amsuabufr amsua n19 amsua_n19 0.0 1 0
- mhsbufr mhs n19 mhs_n19 0.0 1 0
- tcvitl tcp null tcp 0.0 0 0
- satwndbufr uv null uv 0.0 0 0
- atmsbufr atms npp atms_npp 0.0 1 0
- crisbufr cris npp cris_npp 0.0 1 0
- crisfsbufr cris-fsr npp cris-fsr_npp 0.0 1 0
- seviribufr seviri m08 seviri_m08 0.0 1 0
- seviribufr seviri m09 seviri_m09 0.0 1 0
- seviribufr seviri m10 seviri_m10 0.0 1 0
- seviribufr seviri m11 seviri_m11 0.0 1 0
- gsnd1bufr sndrd1 g15 sndrD1_g15 0.0 1 0
- gsnd1bufr sndrd2 g15 sndrD2_g15 0.0 1 0
- gsnd1bufr sndrd3 g15 sndrD3_g15 0.0 1 0
- gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 1 0
- prepbufr mta_cld null mta_cld 1.0 0 0
- prepbufr gos_ctp null gos_ctp 1.0 0 0
- lgycldbufr larccld null larccld 1.0 0 0
-::
- &SUPEROB_RADAR
- del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000.,
- l2superob_only=.false.,
- /
- &LAG_DATA
- /
- &HYBRID_ENSEMBLE
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- /
- &CHEM
- /
- &SINGLEOB_TEST
- /
- &NST
- /
-"
-;;
-
- cmaq_binary)
-
-# Define namelist for cmaq binary run
-
-export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=50,niter(2)=50,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- gencode=78,qoption=2,
- factqmin=0.0,factqmax=0.0,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,
- nhr_assimilation=3,l_foto=.false.,
- use_pbl=.false.,use_compress=.false.,
- diag_conv=.true.,lrun_subdirs=.true.,
- $SETUP
- /
- &GRIDOPTS
- JCAP=$JCAP,NLAT=$NLAT,NLON=$LONA,nsig=$LEVS,
- wrf_nmm_regional=.false.,wrf_mass_regional=.false.,
- cmaq_regional=.true.,diagnostic_reg=.false.,
- filled_grid=.false.,half_grid=.true.,netcdf=.false.,
- /
- &BKGERR
- hzscl=0.373,0.746,1.50,
- vs=1.0,bw=0.,fstat=.true.,
- /
- &ANBKGERR
- anisotropic=.false.,an_vs=1.0,ngauss=1,
- an_flen_u=-5.,an_flen_t=3.,an_flen_z=-200.,
- ifilt_ord=2,npass=3,normal=-200,grid_ratio=4.,nord_f2a=4,
- /
- &JCOPTS
- /
- &STRONGOPTS
- nstrong=0,nvmodes_keep=20,
- period_max=3.,baldiag_full=.true.,baldiag_inc=.true.,
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.true.,c_varqc=0.02,vadfile='prepbufr',oberrflg=.false.,njqc=.false.,vqc=.true.,
- /
- &OBS_INPUT
- dmesh(1)=120.0,dmesh(2)=60.0,dmesh(3)=60.0,dmesh(4)=60.0,
- dmesh(5)=120,time_window_max=1.5,
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- anowbufr pm2_5 null TEOM 1.0 0 0
- /
-!max name length for dfile=13
-!max name length for dtype=10
- &SUPEROB_RADAR
- del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000.,
- l2superob_only=.false.,
-::
- &LAG_DATA
- /
- &HYBRID_ENSEMBLE
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- /
- &CHEM
- berror_chem=.true.,
- oneobtest_chem=.false.,
- maginnov_chem=60,magoberr_chem=2.,oneob_type_chem='pm2_5',
- oblat_chem=45.,oblon_chem=270.,obpres_chem=1000.,
- diag_incr=.true.,elev_tolerance=500.,tunable_error=0.5,
- in_fname="\""${cmaq_input}"\"",out_fname="\""${cmaq_output}"\"",
- incr_fname="\""${chem_increment}"\"",
-!diag_incr for diagnostic increment output
- /
- &SINGLEOB_TEST
- maginnov=5,magoberr=0.1,oneob_type='t',
- oblat=45.,oblon=270.,obpres=1000.,obdattim=${adate},
- obhourset=0.,
- /
- &NST
- /
-"
-;;
-
- hwrf_nmm_d2)
-
-# Define namelist for hwrf nmm d2 run
-
-export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=50,niter(2)=50,niter_no_qc(1)=20,niter_no_qc(2)=0,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- gencode=78,qoption=2,
- factqmin=0.0,factqmax=0.0,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,
- nhr_assimilation=6,l_foto=.false.,
- use_pbl=.true.,use_compress=.false.,
- print_diag_pcg=.true.,
- use_gfs_stratosphere=$USE_GFS_STRATOSPHERE,
- use_gfs_ozone=$USE_GFS_OZONE,
- regional_ozone=$REGIONAL_OZONE,
- nsig_ext=12,gpstop=50.,
- $SETUP
+ netcdf_diag=.true.,binary_diag=.false.,
+ newpc4pred=.true., adp_anglebc=.true., angord=4,
+ passive_bc=.false., use_edges=.false., emiss_bc=.true.,
+ diag_precon=.true., step_start=1.e-3, upd_pred(1)=0,
+ upd_pred(2)=0,upd_pred(3)=0,upd_pred(4)=0,
+ upd_pred(5)=0,upd_pred(6)=0,upd_pred(7)=0,
+ upd_pred(8)=0,upd_pred(9)=0,upd_pred(10)=0,
+ upd_pred(11)=0,upd_pred(12)=0,
+ lread_obs_save=.false.,
+ lread_obs_skip=.false.,
+ ens_nstarthr=6,
+ lwrite_predterms=.false.,lwrite_peakwt=.false.,reduce_diag=.false.,
/
&GRIDOPTS
- JCAP=$JCAP,JCAP_B=$JCAP_B,NLAT=$NLAT,NLON=$NLON,nsig=$LEVS,
- wrf_nmm_regional=.true.,wrf_mass_regional=.false.,
- diagnostic_reg=.false.,
- filled_grid=.false.,half_grid=.true.,netcdf=$NETCDF,
+ fv3_regional=.true.,grid_ratio_fv3_regional=1,nvege_type=20,
/
&BKGERR
- hzscl=0.25,0.5,1.0,
- vs=0.6,bw=0.,fstat=.false.,
- /
+ vs=1.0,
+ hzscl=0.2,0.4,0.8,
+ bw=0.,
+ fstat=.false.,
+/
&ANBKGERR
anisotropic=.false.,an_vs=1.0,ngauss=1,
an_flen_u=-5.,an_flen_t=3.,an_flen_z=-200.,
@@ -1853,299 +613,336 @@ export gsi_namelist="
/
&OBSQC
dfact=0.75,dfact1=3.0,erradar_inflate=1.0,tdrerr_inflate=.true.,
- noiqc=.true.,c_varqc=0.02,vadfile='prepbufr',oberrflg=.false.,njqc=.false.,vqc=.true.,
+ noiqc=.true.,c_varqc=0.03333,vadfile='prepbufr',njqc=.false.,vqc=.true.,vadwnd_l2rw_qc=.false.,
+ q_doe_a_136=0.65,
+ q_doe_b_136=0.0003,
+ q_doe_a_137=0.75,
+ q_doe_b_137=0.0003,
+ t_doe_a_136=0.75,
+ t_doe_b_136=0.2,
+ t_doe_a_137=0.7,
+ t_doe_b_137=0.2,
+ uv_doe_a_236=0.5,
+ uv_doe_b_236=0.85,
+ uv_doe_a_237=0.5,
+ uv_doe_b_237=0.85,
+ uv_doe_a_213=0.4,
+ uv_doe_b_213=1.0,
/
&OBS_INPUT
dmesh(1)=90.0,dmesh(2)=45.0,dmesh(3)=45.0,dmesh(4)=45.0,dmesh(5)=90,time_window_max=3.0,l_foreaft_thin=.false.,
/
OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 0.0 0 0
- prepbufr t null t 0.0 0 0
- prepbufr q null q 0.0 0 0
- prepbufr pw null pw 0.0 0 0
- prepbufr uv null uv 0.0 0 0
- satwndbufr uv null uv 0.0 0 0
- prepbufr spd null spd 0.0 0 0
- prepbufr dw null dw 0.0 0 0
- radarbufr rw null l3rw 0.0 0 0
- l2rwbufr rw null l2rw 0.0 0 0
- prepbufr sst null sst 0.0 0 0
- tcvitl tcp null tcp 0.0 0 0
- tldplrbufr rw null rw 0.0 0 0
- hdobbufr uv null uv 0.0 0 0
- hdobbufr t null t 0.0 0 0
- hdobbufr q null q 0.0 0 0
- hdobbufr spd null spd 0.0 0 0
- gpsrobufr gps_bnd null gps 0.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
- hirs3bufr hirs3 n17 hirs3_n17 0.0 1 0
- hirs4bufr hirs4 metop-a hirs4_metop-a 0.0 1 1
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs_aqua 0.0 1 1
- amsuabufr amsua n15 amsua_n15 0.0 2 1
- amsuabufr amsua n18 amsua_n18 0.0 2 1
- amsuabufr amsua metop-a amsua_metop-a 0.0 2 1
- airsbufr amsua aqua amsua_aqua 0.0 2 1
- amsubbufr amsub n17 amsub_n17 0.0 3 1
- mhsbufr mhs n18 mhs_n18 0.0 3 1
- mhsbufr mhs metop-a mhs_metop-a 0.0 3 1
- ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 4 0
- amsrebufr amsre_mid aqua amsre_aqua 0.0 4 0
- amsrebufr amsre_hig aqua amsre_aqua 0.0 4 0
- ssmisbufr ssmis f16 ssmis_f16 0.0 4 0
- ssmisbufr ssmis f17 ssmis_f17 0.0 4 0
- ssmisbufr ssmis f18 ssmis_f18 0.0 4 0
- ssmisbufr ssmis f19 ssmis_f19 0.0 4 0
- gsnd1bufr sndrd1 g12 sndrD1_g12 0.0 5 0
- gsnd1bufr sndrd2 g12 sndrD2_g12 0.0 5 0
- gsnd1bufr sndrd3 g12 sndrD3_g12 0.0 5 0
- gsnd1bufr sndrd4 g12 sndrD4_g12 0.0 5 0
- gsnd1bufr sndrd1 g11 sndrD1_g11 0.0 5 0
- gsnd1bufr sndrd2 g11 sndrD2_g11 0.0 5 0
- gsnd1bufr sndrd3 g11 sndrD3_g11 0.0 5 0
- gsnd1bufr sndrd4 g11 sndrD4_g11 0.0 5 0
- gsnd1bufr sndrd1 g13 sndrD1_g13 0.0 5 0
- gsnd1bufr sndrd2 g13 sndrD2_g13 0.0 5 0
- gsnd1bufr sndrd3 g13 sndrD3_g13 0.0 5 0
- gsnd1bufr sndrd4 g13 sndrD4_g13 0.0 5 0
- iasibufr iasi metop-a iasi_metop-a 0.0 1 1
- gomebufr gome metop-a gome_metop-a 0.0 2 0
- omibufr omi aura omi_aura 0.0 2 0
- sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
- hirs4bufr hirs4 n19 hirs4_n19 0.0 1 1
- amsuabufr amsua n19 amsua_n19 0.0 2 1
- mhsbufr mhs n19 mhs_n19 0.0 3 1
- seviribufr seviri m08 seviri_m08 0.0 1 0
- seviribufr seviri m09 seviri_m09 0.0 1 0
- seviribufr seviri m10 seviri_m10 0.0 1 0
- seviribufr seviri m11 seviri_m11 0.0 1 0
- hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 0
- amsuabufr amsua metop-b amsua_metop-b 0.0 2 0
- mhsbufr mhs metop-b mhs_metop-b 0.0 3 0
- iasibufr iasi metop-b iasi_metop-b 0.0 1 0
- gomebufr gome metop-b gome_metop-b 0.0 2 0
- atmsbufr atms npp atms_npp 0.0 2 0
- atmsbufr atms n20 atms_n20 0.0 2 0
- crisbufr cris npp cris_npp 0.0 1 0
- crisfsbufr cris-fsr npp cris-fsr_npp 0.0 1 0
- crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 1 0
- gsnd1bufr sndrd1 g14 sndrD1_g14 0.0 5 0
- gsnd1bufr sndrd2 g14 sndrD2_g14 0.0 5 0
- gsnd1bufr sndrd3 g14 sndrD3_g14 0.0 5 0
- gsnd1bufr sndrd4 g14 sndrD4_g14 0.0 5 0
- gsnd1bufr sndrd1 g15 sndrD1_g15 0.0 5 0
- gsnd1bufr sndrd2 g15 sndrD2_g15 0.0 5 0
- gsnd1bufr sndrd3 g15 sndrD3_g15 0.0 5 0
- gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 5 0
- ompsnpbufr ompsnp npp ompsnp_npp 0.0 0 0
- ompstcbufr ompstc8 npp ompstc8_npp 0.0 2 0
+! dfile dtype dplat dsis dval dthin dsfcalc
+ prepbufr ps null ps 0.0 0 0
+ prepbufr t null t 0.0 0 0
+ prepbufr_profl t null t 0.0 0 0
+ prepbufr q null q 0.0 0 0
+ prepbufr_profl q null q 0.0 0 0
+ prepbufr pw null pw 0.0 0 0
+ prepbufr uv null uv 0.0 0 0
+ prepbufr_profl uv null uv 0.0 0 0
+ satwndbufr uv null uv 0.0 0 0
+ satwhrbufr uv null uv 0.0 0 0
+ prepbufr spd null spd 0.0 0 0
+ prepbufr dw null dw 0.0 0 0
+ radarbufr rw null rw 0.0 0 0
+ prepbufr sst null sst 0.0 0 0
+ tcvitl tcp null tcp 0.0 0 0
+ tldplrbufr rw null rw 0.0 0 0
+ l2rwbufr rw null l2rw 0.0 0 0
+ hdobbufr uv null uv 0.0 0 0
+ hdobbufr t null t 0.0 0 0
+ hdobbufr q null q 0.0 0 0
+ hdobbufr spd null spd 0.0 0 0
+ gpsrobufr gps_bnd null gps 0.0 0 0
+ ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
+ tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
+ sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
+ sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
+ sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
+ gimgrbufr goes_img g11 imgr_g11 0.0 1 0
+ gimgrbufr goes_img g12 imgr_g12 0.0 1 0
+ airsbufr airs aqua airs_aqua 0.0 1 1
+ amsuabufr amsua n15 amsua_n15 0.0 2 1
+ amsuabufr amsua n18 amsua_n18 0.0 2 1
+ amsuabufr amsua metop-a amsua_metop-a 0.0 2 1
+ airsbufr amsua aqua amsua_aqua 0.0 2 1
+ amsubbufr amsub n17 amsub_n17 0.0 3 1
+ mhsbufr mhs n18 mhs_n18 0.0 3 1
+ mhsbufr mhs metop-a mhs_metop-a 0.0 3 1
+ ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
+ amsrebufr amsre_low aqua amsre_aqua 0.0 4 0
+ amsrebufr amsre_mid aqua amsre_aqua 0.0 4 0
+ amsrebufr amsre_hig aqua amsre_aqua 0.0 4 0
+ ssmisbufr ssmis f16 ssmis_f16 0.0 4 0
+ ssmisbufr ssmis f17 ssmis_f17 0.0 4 0
+ ssmisbufr ssmis f18 ssmis_f18 0.0 4 0
+ ssmisbufr ssmis f19 ssmis_f19 0.0 4 0
+ gsnd1bufr sndrd1 g12 sndrD1_g12 0.0 5 0
+ gsnd1bufr sndrd2 g12 sndrD2_g12 0.0 5 0
+ gsnd1bufr sndrd3 g12 sndrD3_g12 0.0 5 0
+ gsnd1bufr sndrd4 g12 sndrD4_g12 0.0 5 0
+ gsnd1bufr sndrd1 g11 sndrD1_g11 0.0 5 0
+ gsnd1bufr sndrd2 g11 sndrD2_g11 0.0 5 0
+ gsnd1bufr sndrd3 g11 sndrD3_g11 0.0 5 0
+ gsnd1bufr sndrd4 g11 sndrD4_g11 0.0 5 0
+ gsnd1bufr sndrd1 g13 sndrD1_g13 0.0 5 0
+ gsnd1bufr sndrd2 g13 sndrD2_g13 0.0 5 0
+ gsnd1bufr sndrd3 g13 sndrD3_g13 0.0 5 0
+ gsnd1bufr sndrd4 g13 sndrD4_g13 0.0 5 0
+ iasibufr iasi metop-a iasi_metop-a 0.0 1 1
+ gomebufr gome metop-a gome_metop-a 0.0 2 0
+ omibufr omi aura omi_aura 0.0 2 0
+ sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
+ amsuabufr amsua n19 amsua_n19 0.0 2 1
+ mhsbufr mhs n19 mhs_n19 0.0 3 1
+ seviribufr seviri m08 seviri_m08 0.0 1 0
+ seviribufr seviri m09 seviri_m09 0.0 1 0
+ seviribufr seviri m10 seviri_m10 0.0 1 0
+ amsuabufr amsua metop-b amsua_metop-b 0.0 2 0
+ mhsbufr mhs metop-b mhs_metop-b 0.0 3 0
+ iasibufr iasi metop-b iasi_metop-b 0.0 1 0
+ gomebufr gome metop-b gome_metop-b 0.0 2 0
+ atmsbufr atms npp atms_npp 0.0 2 0
+ atmsbufr atms n20 atms_n20 0.0 2 0
+ crisbufr cris npp cris_npp 0.0 1 0
+ crisfsbufr cris-fsr npp cris-fsr_npp 0.0 1 0
+ crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 1 0
+ gsnd1bufr sndrd1 g14 sndrD1_g14 0.0 5 0
+ gsnd1bufr sndrd2 g14 sndrD2_g14 0.0 5 0
+ gsnd1bufr sndrd3 g14 sndrD3_g14 0.0 5 0
+ gsnd1bufr sndrd4 g14 sndrD4_g14 0.0 5 0
+ gsnd1bufr sndrd1 g15 sndrD1_g15 0.0 5 0
+ gsnd1bufr sndrd2 g15 sndrD2_g15 0.0 5 0
+ gsnd1bufr sndrd3 g15 sndrD3_g15 0.0 5 0
+ gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 5 0
+ oscatbufr uv null uv 0.0 0 0
+ mlsbufr mls30 aura mls30_aura 0.0 0 0
+ amsr2bufr amsr2 gcom-w1 amsr2_gcom-w1 0.0 3 0
+ gmibufr gmi gpm gmi_gpm 0.0 3 0
+ saphirbufr saphir meghat saphir_meghat 0.0 3 0
+ ahibufr ahi himawari8 ahi_himawari8 0.0 3 0
::
&SUPEROB_RADAR
- del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000.,
- l2superob_only=.false.,
- /
+ del_azimuth=5.,del_elev=.25,del_range=10000.,del_time=1.0,elev_angle_max=5.,minnum=1,range_max=200000.,
+ l2superob_only=.false.,radar_sites=.false.,
+ radar_box=.true.,radar_rmesh=10,radar_zmesh=500,
+ /
+SUPEROB_RADAR::
+ KBRO 1
+ KCRP 1
+ KEWX 1
+ KGRX 1
+ KDFX 1
+ KHGX 1
+ KLCH 1
+ KLIX 1
+ KPOE 1
+ KSHV 1
+ KDGX 1
+ KMOB 1
+ KEVX 1
+ KEOX 1
+ KMXX 1
+ KBMX 1
+ KTLH 1
+ KTBW 1
+ KBYX 1
+ KAMX 1
+ KMLB 1
+ KJAX 1
+ KVAX 1
+ KJGX 1
+ KFFC 1
+ KCLX 1
+ KCAE 1
+ KGSP 1
+ KLTX 1
+ KMHX 1
+ KRAX 1
+ KAKQ 1
+ KFCX 1
+ KLWX 1
+ KDOX 1
+ KCCX 1
+ KDIX 1
+ KOKX 1
+ KENX 1
+ KBGM 1
+ KCXX 1
+ KBOX 1
+ KGYX 1
+ KCBW 1
+ TJUA 1
+ PHWA 1
+ PHKI 1
+ PHMO 1
+ PHKM 1
+::
+/
&LAG_DATA
/
&HYBRID_ENSEMBLE
- l_hyb_ens=.true.,n_ens=10,uv_hyb_ens=.true.,beta_s0=0.2,
- readin_beta=.true.,
- s_ens_h=300,s_ens_v=-0.5,readin_localization=.false.,
- generate_ens=.false.,regional_ensemble_option=1,grid_ratio_ens=1,
- pseudo_hybens=.false.,merge_two_grid_ensperts=.false.,
- pwgtflg=.false.,aniso_a_en=.false.,
- nlon_ens=165,nlat_ens=335,jcap_ens=0,jcap_ens_test=0,
+ l_hyb_ens=.true.,
+ n_ens=${N_ENS},
+ uv_hyb_ens=.true.,
+ beta_s0=${BETA_S0},
+ s_ens_h=150,
+ s_ens_v=-0.5,
+ readin_localization=.false.,
+ generate_ens=.false.,
+ regional_ensemble_option=${REGIONAL_ENSEMBLE_OPTION},
+ grid_ratio_ens=${GRID_RATIO_ENS},
+ pseudo_hybens=.false.,
+ merge_two_grid_ensperts=F,
+ pwgtflg=F,
+ aniso_a_en=.false.,
+ nlon_ens=387,
+ nlat_ens=777,
+ write_ens_sprd=F,
+ l_both_fv3sar_gfs_ens=${l_both_fv3sar_gfs_ens},
+ n_ens_gfs=${n_ens_gfs},
+ n_ens_fv3sar=${n_ens_fv3sar},
/
&RAPIDREFRESH_CLDSURF
dfi_radar_latent_heat_time_period=30.0,
/
&CHEM
/
+ &NST
+ /
&SINGLEOB_TEST
maginnov=1.0,magoberr=0.8,oneob_type='t',
- oblat=38.,oblon=279.,obpres=500.,obdattim=${adate},
+ oblat=38.,oblon=279.,obpres=500.,obdattim=2020040500,
obhourset=0.,
/
- &NST
- /
"
;;
+ rrfs_enkf_conv)
- hwrf_nmm_d3)
-
-# Define namelist for hwrf nmm d3 run
+# Define namelist for rrfs EnKF run
export gsi_namelist="
- &SETUP
- miter=2,niter(1)=50,niter(2)=50,niter_no_qc(1)=20,niter_no_qc(2)=0,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- gencode=78,qoption=2,
- factqmin=0.0,factqmax=0.0,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,
- nhr_assimilation=6,l_foto=.false.,
- use_pbl=.true.,use_compress=.false.,
- print_diag_pcg=.true.,
- use_gfs_stratosphere=$USE_GFS_STRATOSPHERE,
- use_gfs_ozone=$USE_GFS_OZONE,
- regional_ozone=$REGIONAL_OZONE,
- nsig_ext=12,gpstop=50.,
- $SETUP
- /
- &GRIDOPTS
- JCAP=$JCAP,JCAP_B=$JCAP_B,NLAT=$NLAT,NLON=$NLON,nsig=$LEVS,
- wrf_nmm_regional=.true.,wrf_mass_regional=.false.,
- diagnostic_reg=.false.,
- filled_grid=.false.,half_grid=.true.,netcdf=$NETCDF,
- /
- &BKGERR
- hzscl=0.2,0.4,0.8,
- vs=0.6,bw=0.,fstat=.false.,
- /
- &ANBKGERR
- anisotropic=.false.,an_vs=1.0,ngauss=1,
- an_flen_u=-5.,an_flen_t=3.,an_flen_z=-200.,
- ifilt_ord=2,npass=3,normal=-200,grid_ratio=4.,nord_f2a=4,
- /
- &JCOPTS
- /
- &STRONGOPTS
- tlnmc_option=0,reg_tlnmc_type=1,nstrong=1,nvmodes_keep=8,period_max=6.,
- period_width=1.5,baldiag_full=.false.,baldiag_inc=.false.,
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,erradar_inflate=1.0,tdrerr_inflate=.true.,
- noiqc=.true.,c_varqc=0.02,vadfile='prepbufr',oberrflg=.false.,njqc=.false.,vqc=.true.,
- /
- &OBS_INPUT
- dmesh(1)=90.0,dmesh(2)=45.0,dmesh(3)=45.0,dmesh(4)=45.0,dmesh(5)=90,time_window_max=3.0,l_foreaft_thin=.false.,
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 0.0 0 0
- prepbufr t null t 0.0 0 0
- prepbufr q null q 0.0 0 0
- prepbufr pw null pw 0.0 0 0
- prepbufr uv null uv 0.0 0 0
- satwndbufr uv null uv 0.0 0 0
- prepbufr spd null spd 0.0 0 0
- prepbufr dw null dw 0.0 0 0
- radarbufr rw null l3rw 0.0 0 0
- l2rwbufr rw null l2rw 0.0 0 0
- prepbufr sst null sst 0.0 0 0
- tcvitl tcp null tcp 0.0 0 0
- tldplrbufr rw null rw 0.0 0 0
- hdobbufr uv null uv 0.0 0 0
- hdobbufr t null t 0.0 0 0
- hdobbufr q null q 0.0 0 0
- hdobbufr spd null spd 0.0 0 0
- gpsrobufr gps_bnd null gps 0.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
- hirs3bufr hirs3 n17 hirs3_n17 0.0 1 0
- hirs4bufr hirs4 metop-a hirs4_metop-a 0.0 1 1
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs_aqua 0.0 1 1
- amsuabufr amsua n15 amsua_n15 0.0 2 1
- amsuabufr amsua n18 amsua_n18 0.0 2 1
- amsuabufr amsua metop-a amsua_metop-a 0.0 2 1
- airsbufr amsua aqua amsua_aqua 0.0 2 1
- amsubbufr amsub n17 amsub_n17 0.0 3 1
- mhsbufr mhs n18 mhs_n18 0.0 3 1
- mhsbufr mhs metop-a mhs_metop-a 0.0 3 1
- ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 4 0
- amsrebufr amsre_mid aqua amsre_aqua 0.0 4 0
- amsrebufr amsre_hig aqua amsre_aqua 0.0 4 0
- ssmisbufr ssmis f16 ssmis_f16 0.0 4 0
- ssmisbufr ssmis f17 ssmis_f17 0.0 4 0
- ssmisbufr ssmis f18 ssmis_f18 0.0 4 0
- ssmisbufr ssmis f19 ssmis_f19 0.0 4 0
- gsnd1bufr sndrd1 g12 sndrD1_g12 0.0 5 0
- gsnd1bufr sndrd2 g12 sndrD2_g12 0.0 5 0
- gsnd1bufr sndrd3 g12 sndrD3_g12 0.0 5 0
- gsnd1bufr sndrd4 g12 sndrD4_g12 0.0 5 0
- gsnd1bufr sndrd1 g11 sndrD1_g11 0.0 5 0
- gsnd1bufr sndrd2 g11 sndrD2_g11 0.0 5 0
- gsnd1bufr sndrd3 g11 sndrD3_g11 0.0 5 0
- gsnd1bufr sndrd4 g11 sndrD4_g11 0.0 5 0
- gsnd1bufr sndrd1 g13 sndrD1_g13 0.0 5 0
- gsnd1bufr sndrd2 g13 sndrD2_g13 0.0 5 0
- gsnd1bufr sndrd3 g13 sndrD3_g13 0.0 5 0
- gsnd1bufr sndrd4 g13 sndrD4_g13 0.0 5 0
- iasibufr iasi metop-a iasi_metop-a 0.0 1 1
- gomebufr gome metop-a gome_metop-a 0.0 2 0
- omibufr omi aura omi_aura 0.0 2 0
- sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
- hirs4bufr hirs4 n19 hirs4_n19 0.0 1 1
- amsuabufr amsua n19 amsua_n19 0.0 2 1
- mhsbufr mhs n19 mhs_n19 0.0 3 1
- seviribufr seviri m08 seviri_m08 0.0 1 0
- seviribufr seviri m09 seviri_m09 0.0 1 0
- seviribufr seviri m10 seviri_m10 0.0 1 0
- seviribufr seviri m11 seviri_m11 0.0 1 0
- hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 0
- amsuabufr amsua metop-b amsua_metop-b 0.0 2 0
- mhsbufr mhs metop-b mhs_metop-b 0.0 3 0
- iasibufr iasi metop-b iasi_metop-b 0.0 1 0
- gomebufr gome metop-b gome_metop-b 0.0 2 0
- atmsbufr atms npp atms_npp 0.0 2 0
- atmsbufr atms n20 atms_n20 0.0 2 0
- crisbufr cris npp cris_npp 0.0 1 0
- crisfsbufr cris-fsr npp cris-fsr_npp 0.0 1 0
- crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 1 0
- gsnd1bufr sndrd1 g14 sndrD1_g14 0.0 5 0
- gsnd1bufr sndrd2 g14 sndrD2_g14 0.0 5 0
- gsnd1bufr sndrd3 g14 sndrD3_g14 0.0 5 0
- gsnd1bufr sndrd4 g14 sndrD4_g14 0.0 5 0
- gsnd1bufr sndrd1 g15 sndrD1_g15 0.0 5 0
- gsnd1bufr sndrd2 g15 sndrD2_g15 0.0 5 0
- gsnd1bufr sndrd3 g15 sndrD3_g15 0.0 5 0
- gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 5 0
- ompsnpbufr ompsnp npp ompsnp_npp 0.0 0 0
- ompstcbufr ompstc8 npp ompstc8_npp 0.0 2 0
-::
- &SUPEROB_RADAR
- del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000.,
- l2superob_only=.false.,
- /
- &LAG_DATA
- /
- &HYBRID_ENSEMBLE
- l_hyb_ens=.true.,n_ens=10,uv_hyb_ens=.true.,beta_s0=0.2,
- readin_beta=.true.,
- s_ens_h=150,s_ens_v=-0.5,readin_localization=.false.,
- generate_ens=.false.,regional_ensemble_option=1,grid_ratio_ens=1,
- pseudo_hybens=.false.,merge_two_grid_ensperts=.false.,
- pwgtflg=.false.,aniso_a_en=.false.,
- nlon_ens=249,nlat_ens=499,jcap_ens=0,jcap_ens_test=0,
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- /
- &CHEM
- /
- &SINGLEOB_TEST
- maginnov=1.0,magoberr=0.8,oneob_type='t',
- oblat=38.,oblon=279.,obpres=500.,obdattim=${adate},
- obhourset=0.,
- /
- &NST
- /
+ &nam_enkf
+ datestring=${rrfs_enkf_adate},datapath='${tmpdir}/',
+ analpertwtnh=1.10,analpertwtsh=1.10,analpertwttr=1.10,
+ covinflatemax=1.e2,covinflatemin=1,pseudo_rh=.true.,iassim_order=0,
+ corrlengthnh=300,corrlengthsh=300,corrlengthtr=300,
+ lnsigcutoffnh=0.5,lnsigcutoffsh=0.5,lnsigcutofftr=0.5,
+ lnsigcutoffpsnh=0.5,lnsigcutoffpssh=0.5,lnsigcutoffpstr=0.5,
+ lnsigcutoffsatnh=0.5,lnsigcutoffsatsh=0.5,lnsigcutoffsattr=0.5,
+ obtimelnh=1.e30,obtimelsh=1.e30,obtimeltr=1.e30,
+ saterrfact=1.0,numiter=1,
+ sprd_tol=1.e30,paoverpb_thresh=0.98,
+ nlons=420,nlats= 252, nlevs= 65,nanals=5,
+ deterministic=.true.,sortinc=.true.,lupd_satbiasc=.false.,
+ reducedgrid=.true.,readin_localization=.false.,
+ use_gfs_nemsio=.true.,imp_physics=99,lupp=.false.,
+ univaroz=.false.,adp_anglebc=.true.,angord=4,use_edges=.false.,emiss_bc=.true.,
+ lobsdiag_forenkf=.false.,
+ write_spread_diag=.false.,
+ netcdf_diag=.true.,
+ fv3_native=.true.,
+ /
+ &satobs_enkf
+ sattypes_rad(1) = 'amsua_n15', dsis(1) = 'amsua_n15',
+ sattypes_rad(2) = 'amsua_n18', dsis(2) = 'amsua_n18',
+ sattypes_rad(3) = 'amsua_n19', dsis(3) = 'amsua_n19',
+ sattypes_rad(4) = 'amsub_n16', dsis(4) = 'amsub_n16',
+ sattypes_rad(5) = 'amsub_n17', dsis(5) = 'amsub_n17',
+ sattypes_rad(6) = 'amsua_aqua', dsis(6) = 'amsua_aqua',
+ sattypes_rad(7) = 'amsua_metop-a', dsis(7) = 'amsua_metop-a',
+ sattypes_rad(8) = 'airs_aqua', dsis(8) = 'airs_aqua',
+ sattypes_rad(9) = 'hirs3_n17', dsis(9) = 'hirs3_n17',
+ sattypes_rad(10)= 'hirs4_n19', dsis(10)= 'hirs4_n19',
+ sattypes_rad(11)= 'hirs4_metop-a', dsis(11)= 'hirs4_metop-a',
+ sattypes_rad(12)= 'mhs_n18', dsis(12)= 'mhs_n18',
+ sattypes_rad(13)= 'mhs_n19', dsis(13)= 'mhs_n19',
+ sattypes_rad(14)= 'mhs_metop-a', dsis(14)= 'mhs_metop-a',
+ sattypes_rad(15)= 'goes_img_g11', dsis(15)= 'imgr_g11',
+ sattypes_rad(16)= 'goes_img_g12', dsis(16)= 'imgr_g12',
+ sattypes_rad(17)= 'goes_img_g13', dsis(17)= 'imgr_g13',
+ sattypes_rad(18)= 'goes_img_g14', dsis(18)= 'imgr_g14',
+ sattypes_rad(19)= 'goes_img_g15', dsis(19)= 'imgr_g15',
+ sattypes_rad(20)= 'avhrr_n18', dsis(20)= 'avhrr3_n18',
+ sattypes_rad(21)= 'avhrr_metop-a', dsis(21)= 'avhrr3_metop-a',
+ sattypes_rad(22)= 'avhrr_n19', dsis(22)= 'avhrr3_n19',
+ sattypes_rad(23)= 'amsre_aqua', dsis(23)= 'amsre_aqua',
+ sattypes_rad(24)= 'ssmis_f16', dsis(24)= 'ssmis_f16',
+ sattypes_rad(25)= 'ssmis_f17', dsis(25)= 'ssmis_f17',
+ sattypes_rad(26)= 'ssmis_f18', dsis(26)= 'ssmis_f18',
+ sattypes_rad(27)= 'ssmis_f19', dsis(27)= 'ssmis_f19',
+ sattypes_rad(28)= 'ssmis_f20', dsis(28)= 'ssmis_f20',
+ sattypes_rad(29)= 'sndrd1_g11', dsis(29)= 'sndrD1_g11',
+ sattypes_rad(30)= 'sndrd2_g11', dsis(30)= 'sndrD2_g11',
+ sattypes_rad(31)= 'sndrd3_g11', dsis(31)= 'sndrD3_g11',
+ sattypes_rad(32)= 'sndrd4_g11', dsis(32)= 'sndrD4_g11',
+ sattypes_rad(33)= 'sndrd1_g12', dsis(33)= 'sndrD1_g12',
+ sattypes_rad(34)= 'sndrd2_g12', dsis(34)= 'sndrD2_g12',
+ sattypes_rad(35)= 'sndrd3_g12', dsis(35)= 'sndrD3_g12',
+ sattypes_rad(36)= 'sndrd4_g12', dsis(36)= 'sndrD4_g12',
+ sattypes_rad(37)= 'sndrd1_g13', dsis(37)= 'sndrD1_g13',
+ sattypes_rad(38)= 'sndrd2_g13', dsis(38)= 'sndrD2_g13',
+ sattypes_rad(39)= 'sndrd3_g13', dsis(39)= 'sndrD3_g13',
+ sattypes_rad(40)= 'sndrd4_g13', dsis(40)= 'sndrD4_g13',
+ sattypes_rad(41)= 'sndrd1_g14', dsis(41)= 'sndrD1_g14',
+ sattypes_rad(42)= 'sndrd2_g14', dsis(42)= 'sndrD2_g14',
+ sattypes_rad(43)= 'sndrd3_g14', dsis(43)= 'sndrD3_g14',
+ sattypes_rad(44)= 'sndrd4_g14', dsis(44)= 'sndrD4_g14',
+ sattypes_rad(45)= 'sndrd1_g15', dsis(45)= 'sndrD1_g15',
+ sattypes_rad(46)= 'sndrd2_g15', dsis(46)= 'sndrD2_g15',
+ sattypes_rad(47)= 'sndrd3_g15', dsis(47)= 'sndrD3_g15',
+ sattypes_rad(48)= 'sndrd4_g15', dsis(48)= 'sndrD4_g15',
+ sattypes_rad(49)= 'iasi_metop-a', dsis(49)= 'iasi_metop-a',
+ sattypes_rad(50)= 'seviri_m08', dsis(50)= 'seviri_m08',
+ sattypes_rad(51)= 'seviri_m09', dsis(51)= 'seviri_m09',
+ sattypes_rad(52)= 'seviri_m10', dsis(52)= 'seviri_m10',
+ sattypes_rad(53)= 'seviri_m11', dsis(53)= 'seviri_m11',
+ sattypes_rad(54)= 'amsua_metop-b', dsis(54)= 'amsua_metop-b',
+ sattypes_rad(55)= 'hirs4_metop-b', dsis(55)= 'hirs4_metop-b',
+ sattypes_rad(56)= 'mhs_metop-b', dsis(56)= 'mhs_metop-b',
+ sattypes_rad(57)= 'iasi_metop-b', dsis(57)= 'iasi_metop-b',
+ sattypes_rad(58)= 'avhrr_metop-b', dsis(58)= 'avhrr3_metop-b',
+ sattypes_rad(59)= 'atms_npp', dsis(59)= 'atms_npp',
+ sattypes_rad(60)= 'atms_n20', dsis(60)= 'atms_n20',
+ sattypes_rad(61)= 'cris_npp', dsis(61)= 'cris_npp',
+ sattypes_rad(62)= 'cris-fsr_npp', dsis(62)= 'cris-fsr_npp',
+ sattypes_rad(63)= 'cris-fsr_n20', dsis(63)= 'cris-fsr_n20',
+ sattypes_rad(64)= 'gmi_gpm', dsis(64)= 'gmi_gpm',
+ sattypes_rad(65)= 'saphir_meghat', dsis(65)= 'saphir_meghat',
+ sattypes_rad(66)= 'amsua_metop-c', dsis(66)= 'amsua_metop-c',
+ sattypes_rad(67)= 'mhs_metop-c', dsis(67)= 'mhs_metop-c',
+ sattypes_rad(68)= 'ahi_himawari8', dsis(68)= 'ahi_himawari8',
+ sattypes_rad(69)= 'abi_g16', dsis(69)= 'abi_g16',
+ sattypes_rad(70)= 'abi_g17', dsis(70)= 'abi_g17',
+ sattypes_rad(71)= 'iasi_metop-c', dsis(71)= 'iasi_metop-c',
+ sattypes_rad(72)= 'viirs-m_npp', dsis(72)= 'viirs-m_npp',
+ sattypes_rad(73)= 'viirs-m_j1', dsis(73)= 'viirs-m_j1',
+ sattypes_rad(74)= 'avhrr_metop-c', dsis(74)= 'avhrr3_metop-c',
+ sattypes_rad(75)= 'abi_g18', dsis(75)= 'abi_g18',
+ sattypes_rad(76)= 'ahi_himawari9', dsis(76)= 'ahi_himawari9',
+ sattypes_rad(77)= 'viirs-m_j2', dsis(77)= 'viirs-m_j2',
+ sattypes_rad(78)= 'atms_n21', dsis(78)= 'atms_n21',
+ sattypes_rad(79)= 'cris-fsr_n21', dsis(79)= 'cris-fsr_n21',
+ /
+ &ozobs_enkf
+ sattypes_oz(1) = 'sbuv2_n16',
+ sattypes_oz(2) = 'sbuv2_n17',
+ sattypes_oz(3) = 'sbuv2_n18',
+ sattypes_oz(4) = 'sbuv2_n19',
+ sattypes_oz(5) = 'omi_aura',
+ sattypes_oz(6) = 'gome_metop-a',
+ sattypes_oz(7) = 'gome_metop-b',
+ sattypes_oz(8) = 'mls30_aura',
+ /
+ &nam_fv3
+ fv3fixpath="XXX",nx_res=${NX_RES:-420},ny_res=${NY_RES-252},ntiles=1,
+ l_fv3reg_filecombined=.false.,
+ /
"
;;
-
global_enkf)
# Define namelist for global enkf run
@@ -2155,7 +952,7 @@ export gsi_namelist="
&nam_enkf
datestring=${global_adate},datapath='${DATA}/',
analpertwtnh=${analpertwt},analpertwtsh=${analpertwt},analpertwttr=${analpertwt},
- covinflatemax=1.e2,covinflatemin=1,pseudo_rh=.true.,iassim_order=0,
+ covinflatemax=1.e2,covinflatemin=1,pseudo_rh=.false.,iassim_order=0,
corrlengthnh=${corrlength},corrlengthsh=${corrlength},corrlengthtr=${corrlength},
lnsigcutoffnh=${lnsigcutoff},lnsigcutoffsh=${lnsigcutoff},lnsigcutofftr=${lnsigcutoff},
lnsigcutoffpsnh=${lnsigcutoff},lnsigcutoffpssh=${lnsigcutoff},lnsigcutoffpstr=${lnsigcutoff},
@@ -2169,7 +966,7 @@ export gsi_namelist="
use_gfs_nemsio=${use_gfs_nemsio},use_gfs_ncio=${use_gfs_ncio},imp_physics=$imp_physics,lupp=$lupp,
univaroz=.false.,adp_anglebc=.true.,angord=4,use_edges=.false.,emiss_bc=.true.,
letkf_flag=${letkf_flag},nobsl_max=${nobsl_max},denkf=${denkf},getkf=${getkf}.,
- nhr_anal=${IAUFHRS_ENKF},nhr_state=${IAUFHRS_ENKF},use_qsatensmean=.true.,
+ nhr_anal=${IAUFHRS_ENKF},nhr_state=${IAUFHRS_ENKF},
lobsdiag_forenkf=$lobsdiag_forenkf,
write_spread_diag=$write_spread_diag,
modelspace_vloc=$modelspace_vloc,
diff --git a/regression/regression_namelists_db.sh b/regression/regression_namelists_db.sh
index 59962a587b..b96c208070 100755
--- a/regression/regression_namelists_db.sh
+++ b/regression/regression_namelists_db.sh
@@ -2,173 +2,7 @@ job_name=$1
case $job_name in
-global_3dvar)
-
-# Define namelist for global run (pcgsoi minimization)
-
-export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=2,niter(2)=1,
- niter_no_qc(1)=1,niter_no_qc(2)=0,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- gencode=82,qoption=2,cwoption=3,
- factqmin=5.0,factqmax=5.0,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,l_foto=.false.,
- use_pbl=.false.,use_compress=.true.,nsig_ext=12,gpstop=50.,
- use_gfs_nemsio=.false.,lrun_subdirs=.true.,
- $SETUP
- /
- &GRIDOPTS
- JCAP=$JCAP,JCAP_B=$JCAP_B,NLAT=$NLAT,NLON=$LONA,nsig=$LEVS,
- regional=.false.,nlayers(63)=3,nlayers(64)=6,
- $GRIDOPTS
- /
- &BKGERR
- vs=0.7,
- hzscl=1.7,0.8,0.5,
- hswgt=0.45,0.3,0.25,
- bw=0.0,norsp=4,
- bkgv_flowdep=.true.,bkgv_rewgtfct=1.5,
- $BKGVERR
- /
- &ANBKGERR
- anisotropic=.false.,
- $ANBKGERR
- /
- &JCOPTS
- ljcdfi=.false.,alphajc=0.0,ljcpdry=.true.,bamp_jcpdry=5.0e7,
- $JCOPTS
- /
- &STRONGOPTS
- tlnmc_option=1,nstrong=1,nvmodes_keep=8,period_max=6.,period_width=1.5,
- baldiag_full=.true.,baldiag_inc=.true.,
- $STRONGOPTS
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.true.,oberrflg=.false.,c_varqc=0.02,
- use_poq7=.true.,njqc=.false.,vqc=.true.,
- $OBSQC
- /
- &OBS_INPUT
- dmesh(1)=1450.0,dmesh(2)=1500.0,time_window_max=0.5,
- $OBSINPUT
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 0.0 0 0
- prepbufr t null t 0.0 0 0
- prepbufr q null q 0.0 0 0
- prepbufr pw null pw 0.0 0 0
- prepbufr uv null uv 0.0 0 0
- satwndbufr uv null uv 0.0 0 0
- prepbufr spd null spd 0.0 0 0
- prepbufr dw null dw 0.0 0 0
- radarbufr rw null rw 0.0 0 0
- prepbufr sst null sst 0.0 0 0
- gpsrobufr $gps_dtype null gps 0.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
- hirs3bufr hirs3 n17 hirs3_n17 0.0 1 1
- hirs4bufr_skip hirs4 metop-a hirs4_metop-a 0.0 1 1
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs_aqua 0.0 1 1
- amsuabufr_skip amsua n15 amsua_n15 0.0 1 1
- amsuabufr_skip amsua n18 amsua_n18 0.0 1 1
- amsuabufr_skip amsua metop-a amsua_metop-a 0.0 1 1
- airsbufr_skip amsua aqua amsua_aqua 0.0 1 1
- amsubbufr amsub n17 amsub_n17 0.0 1 1
- mhsbufr_skip mhs n18 mhs_n18 0.0 1 1
- mhsbufr_skip mhs metop-a mhs_metop-a 0.0 1 1
- ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_mid aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_hig aqua amsre_aqua 0.0 1 0
- ssmisbufr ssmis_las f16 ssmis_f16 0.0 1 0
- ssmisbufr ssmis_uas f16 ssmis_f16 0.0 1 0
- ssmisbufr ssmis_img f16 ssmis_f16 0.0 1 0
- ssmisbufr ssmis_env f16 ssmis_f16 0.0 1 0
- gsnd1bufr_skip sndrd1 g12 sndrD1_g12 0.0 1 0
- gsnd1bufr_skip sndrd2 g12 sndrD2_g12 0.0 1 0
- gsnd1bufr_skip sndrd3 g12 sndrD3_g12 0.0 1 0
- gsnd1bufr_skip sndrd4 g12 sndrD4_g12 0.0 1 0
- gsnd1bufr_skip sndrd1 g11 sndrD1_g11 0.0 1 0
- gsnd1bufr_skip sndrd2 g11 sndrD2_g11 0.0 1 0
- gsnd1bufr sndrd3 g11 sndrD3_g11 0.0 1 0
- gsnd1bufr_skip sndrd4 g11 sndrD4_g11 0.0 1 0
- gsnd1bufr_skip sndrd1 g13 sndrD1_g13 0.0 1 0
- gsnd1bufr_skip sndrd2 g13 sndrD2_g13 0.0 1 0
- gsnd1bufr_skip sndrd3 g13 sndrD3_g13 0.0 1 0
- gsnd1bufr_skip sndrd4 g13 sndrD4_g13 0.0 1 0
- iasibufr iasi metop-a iasi_metop-a 0.0 1 1
- gomebufr gome metop-a gome_metop-a 0.0 2 0
- omibufr omi aura omi_aura 0.0 2 0
- sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
- hirs4bufr hirs4 n19 hirs4_n19 0.0 1 1
- amsuabufr amsua n19 amsua_n19 0.0 1 1
- mhsbufr mhs n19 mhs_n19 0.0 1 1
- tcvitl tcp null tcp 0.0 0 0
- mlsbufr mls30 aura mls30_aura 1.0 0 0
- seviribufr seviri m08 seviri_m08 0.0 1 0
- seviribufr seviri m09 seviri_m09 0.0 1 0
- seviribufr seviri m10 seviri_m10 0.0 1 0
- seviribufr seviri m11 seviri_m11 0.0 1 0
- hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 0
- amsuabufr amsua metop-b amsua_metop-b 0.0 1 0
- mhsbufr mhs metop-b mhs_metop-b 0.0 1 0
- iasibufr iasi metop-b iasi_metop-b 0.0 1 0
- gomebufr gome metop-b gome_metop-b 0.0 2 0
- atmsbufr atms npp atms_npp 0.0 1 0
- atmsbufr atms n20 atms_n20 0.0 1 0
- crisbufr cris npp cris_npp 0.0 1 0
- crisfsbufr cris-fsr npp cris-fsr_npp 0.0 1 0
- crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 1 0
- ompsnpbufr ompsnp npp ompsnp_npp 0.0 0 0
- ompstcbufr ompstc8 npp ompstc8_npp 0.0 2 0
-::
- /
- &SUPEROB_RADAR
- $SUPERRAD
- /
- &LAG_DATA
- /
- &HYBRID_ENSEMBLE
- l_hyb_ens=${HYBENS_GLOBAL},
- n_ens=${ENSEMBLE_SIZE_GLOBAL},
- uv_hyb_ens=${HYBENS_UV_GLOBAL},
- beta_s0=${BETA_S0_GLOBAL},
- readin_beta=.false.,
- s_ens_h=${HYBENS_HOR_SCALE_GLOBAL},
- s_ens_v=${HYBENS_VER_SCALE_GLOBAL},
- generate_ens=${GENERATE_ENS_GLOBAL},
- aniso_a_en=${HYBENS_ANISO_GLOBAL},
- nlon_ens=${LONA},
- nlat_ens=${NLAT},
- jcap_ens=${JCAP},
- jcap_ens_test=${JCAP},
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- /
- &CHEM
- /
- &SINGLEOB_TEST
- maginnov=0.1,magoberr=0.1,oneob_type='t',
- oblat=45.,oblon=180.,obpres=1000.,obdattim=${adate},
- obhourset=0.,
- $SINGLEOB
- /
- &NST
- /
-"
-;;
-
- global_4denvar )
+ global_4denvar)
# Define namelist for global hybrid run
@@ -256,8 +90,6 @@ OBS_INPUT::
sbuvbufr_ sbuv2 n16 sbuv8_n16 0.0 0 0
sbuvbufr_ sbuv2 n17 sbuv8_n17 0.0 0 0
sbuvbufr_ sbuv2 n18 sbuv8_n18 0.0 0 0
- hirs3bufr_ hirs3 n17 hirs3_n17 0.0 1 0
- hirs4bufr_skip hirs4 metop-a hirs4_metop-a 0.0 1 1
gimgrbufr_ goes_img g11 imgr_g11 0.0 1 0
gimgrbufr_ goes_img g12 imgr_g12 0.0 1 0
airsbufr_ airs aqua airs_aqua 0.0 1 1
@@ -291,7 +123,6 @@ OBS_INPUT::
gomebufr gome metop-a gome_metop-a 0.0 2 0
omibufr omi aura omi_aura 0.0 2 0
sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
- hirs4bufr hirs4 n19 hirs4_n19 0.0 1 1
amsuabufr amsua n19 amsua_n19 0.0 1 1
mhsbufr mhs n19 mhs_n19 0.0 1 1
tcvitl tcp null tcp 0.0 0 0
@@ -299,7 +130,6 @@ OBS_INPUT::
seviribufr seviri m09 seviri_m09 0.0 1 0
seviribufr seviri m10 seviri_m10 0.0 1 0
seviribufr seviri m11 seviri_m11 0.0 1 0
- hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 1
amsuabufr amsua metop-b amsua_metop-b 0.0 1 1
mhsbufr mhs metop-b mhs_metop-b 0.0 1 1
iasibufr iasi metop-b iasi_metop-b 0.0 1 1
@@ -344,9 +174,12 @@ OBS_INPUT::
$LAGDATA
/
&HYBRID_ENSEMBLE
- l_hyb_ens=.true.,n_ens=10,beta_s0=0.125,readin_beta=.false.,s_ens_h=800,s_ens_v=-0.8,generate_ens=.false.,uv_hyb_ens=.true.,jcap_ens=190,
- nlat_ens=194,nlon_ens=384,aniso_a_en=.false.,jcap_ens_test=62,oz_univ_static=.false.,readin_localization=.true.,ensemble_path='./ensemble_data/',
- ens_fast_read=.true.,write_ens_sprd=.false.,
+ l_hyb_ens=.true.,n_ens=$NMEM_ENKF,beta_s0=0.125,readin_beta=.false.,
+ generate_ens=.false.,uv_hyb_ens=.true.,jcap_ens=48,nlat_ens=98,nlon_ens=192,
+ ANISO_A_EN=.false.,jcap_ens_test=48,oz_univ_static=.false.,
+ ensemble_path='./ensemble_data/',ens_fast_read=.true.,write_ens_sprd=.false.,
+ s_ens_h=1000.0,450.0,685.0,s_ens_v=-0.5,-0.5,0.0,readin_localization=.false.,
+ global_spectral_filter_sd=.false.,r_ensloccov4scl=1,nsclgrp=2,naensloc=3,
$HYBRID_ENSEMBLE
/
&RAPIDREFRESH_CLDSURF
@@ -468,7 +301,7 @@ OBS_INPUT::
"
;;
- rrfs_3denvar_glbens)
+ rrfs_3denvar_rdasens)
# Define namelist for rrfs 3d hybrid envar run with global ensembles
@@ -477,13 +310,14 @@ export gsi_namelist="
&SETUP
miter=1,niter(1)=2,niter(2)=2,
write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- qoption=2,print_obs_para=.true.,diag_radardbz=.false.,
- if_model_dbz=.false., static_gsi_nopcp_dbz=0.0,
+ qoption=2,print_obs_para=.true.,diag_fed=.true.,diag_radardbz=.false.,
+ if_model_dbz=.true.,if_model_fed=.true.,static_gsi_nopcp_dbz=0.0,if_use_w_vr=.false.,
rmesh_dbz=4.0,rmesh_vr=4.0,zmesh_dbz=1000.0,zmesh_vr=1000.0,
- missing_to_nopcp=.false.,radar_no_thinning=.true.,
+ inflate_dbz_obserr=.true.,missing_to_nopcp=.false.,radar_no_thinning=.true.,
gencode=78,factqmin=0.0,factqmax=0.0,
- iguess=-1,
+ iguess=-1,crtm_coeffs_path='./',
lread_obs_save=.false.,lread_obs_skip=.false.,
+ ens_nstarthr=01,
oneobtest=.false.,retrieval=.false.,
nhr_assimilation=3,l_foto=.false.,
use_pbl=.false.,use_prepb_satwnd=.false.,
@@ -492,8 +326,10 @@ export gsi_namelist="
diag_precon=.true.,step_start=1.e-3,
l4densvar=.false.,nhr_obsbin=3,
use_gfs_nemsio=.false.,use_gfs_ncio=.true.,reset_bad_radbc=.true.,
- netcdf_diag=.false.,binary_diag=.true.,
+ netcdf_diag=.true.,binary_diag=.false.,
l_obsprvdiag=.false.,
+ lwrite_peakwt=.true.,
+ innov_use_model_fed=.true.,
/
&GRIDOPTS
fv3_regional=.true.,grid_ratio_fv3_regional=2.0,nvege_type=20,
@@ -521,7 +357,9 @@ export gsi_namelist="
/
OBS_INPUT::
! dfile dtype dplat dsis dval dthin dsfcalc
+ pm25bufr pm2_5 null TEOM 1.0 0 0
dbzobs.nc dbz null dbz 1.0 0 0
+ fedobs.nc fed null fed 1.0 0 0
prepbufr ps null ps 1.0 0 0
prepbufr t null t 1.0 0 0
prepbufr q null q 1.0 0 0
@@ -552,12 +390,14 @@ OBS_INPUT::
amsuabufr amsua n19 amsua_n19 0.0 2 0
amsuabufr amsua metop-a amsua_metop-a 0.0 2 0
amsuabufr amsua metop-b amsua_metop-b 0.0 2 0
+ amsuabufr amsua metop-c amsua_metop-c 0.0 2 0
airsbufr amsua aqua amsua_aqua 0.0 2 0
amsubbufr amsub n17 amsub_n17 0.0 1 0
mhsbufr mhs n18 mhs_n18 0.0 2 0
mhsbufr mhs n19 mhs_n19 0.0 2 0
mhsbufr mhs metop-a mhs_metop-a 0.0 2 0
mhsbufr mhs metop-b mhs_metop-b 0.0 2 0
+ mhsbufr mhs metop-c mhs_metop-c 0.0 2 0
ssmitbufr ssmi f13 ssmi_f13 0.0 2 0
ssmitbufr ssmi f14 ssmi_f14 0.0 2 0
ssmitbufr ssmi f15 ssmi_f15 0.0 2 0
@@ -586,11 +426,23 @@ OBS_INPUT::
gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 2 0
iasibufr iasi metop-a iasi_metop-a 0.0 2 0
gomebufr gome metop-a gome_metop-a 0.0 2 0
+ omibufr omi aura omi_aura 0.0 2 0
+ sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
+ tcvitl tcp null tcp 0.0 0 0
+ seviribufr seviri m08 seviri_m08 0.0 2 0
+ seviribufr seviri m09 seviri_m09 0.0 2 0
+ seviribufr seviri m10 seviri_m10 0.0 2 0
+ seviribufr seviri m11 seviri_m11 0.0 2 0
+ iasibufr iasi metop-b iasi_metop-b 0.0 2 0
+ iasibufr iasi metop-c iasi_metop-c 0.0 2 0
+ gomebufr gome metop-b gome_metop-b 0.0 2 0
atmsbufr atms npp atms_npp 0.0 2 0
atmsbufr atms n20 atms_n20 0.0 2 0
+ atmsbufr atms n21 atms_n21 0.0 2 0
crisbufr cris npp cris_npp 0.0 2 0
crisfsbufr cris-fsr npp cris-fsr_npp 0.0 2 0
crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 2 0
+ crisfsbufr cris-fsr n21 cris-fsr_n21 0.0 2 0
abibufr abi g16 abi_g16 0.0 2 0
mlsbufr mls30 aura mls30_aura 0.0 0 0
oscatbufr uv null uv 0.0 0 0
@@ -599,6 +451,7 @@ OBS_INPUT::
refInGSI rad_ref null rad_ref 1.0 0 0
lghtInGSI lghtn null lghtn 1.0 0 0
larcInGSI larccld null larccld 1.0 0 0
+ abibufr abi g18 abi_g18 0.0 2 0
::
&SUPEROB_RADAR
del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000., l2superob_only=.false.,
@@ -611,17 +464,30 @@ OBS_INPUT::
q_hyb_ens=.false.,
aniso_a_en=.false.,generate_ens=.false.,
n_ens=${nummem},
- beta_s0=0.15,s_ens_h=110,s_ens_v=3,
- regional_ensemble_option=1,
+ l_both_fv3sar_gfs_ens=.false.,n_ens_gfs=0,n_ens_fv3sar=30,
+ weight_ens_gfs=1.0,weight_ens_fv3sar=1.0,
+ beta_s0=0.15,s_ens_h=328.632,82.1580,4.10790,4.10790,82.1580,s_ens_v=3,3,-0.30125,-0.30125,0.0,
+ regional_ensemble_option=5,
pseudo_hybens = .false.,
- grid_ratio_ens = 3,
+ grid_ratio_ens = 1,
l_ens_in_diff_time=.true.,
ensemble_path='',
i_en_perts_io=1,
jcap_ens=574,
fv3sar_bg_opt=0,
- readin_localization=.true.,
- ens_fast_read=.false.,
+ readin_localization=.false.,
+ parallelization_over_ensmembers=.false.,
+ nsclgrp=2,l_timloc_opt=.false.,ngvarloc=2,naensloc=5,
+ r_ensloccov4tim=1.0,r_ensloccov4var=0.05,r_ensloccov4scl=1.0,
+ global_spectral_filter_sd=.false.,assign_vdl_nml=.false.,vdl_scale=0,
+ vloc_varlist(1,1)='sf ',vloc_varlist(2,1)='w ',vloc_varlist(3,1)='sf ',vloc_varlist(4,1)='w ',
+ vloc_varlist(1,2)='vp ',vloc_varlist(2,2)='qr ',vloc_varlist(3,2)='vp ',vloc_varlist(4,2)='qr ',
+ vloc_varlist(1,3)='ps ',vloc_varlist(2,3)='qs ',vloc_varlist(3,3)='ps ',vloc_varlist(4,3)='qs ',
+ vloc_varlist(1,4)='t ',vloc_varlist(2,4)='qi ',vloc_varlist(3,4)='t ',vloc_varlist(4,4)='qi ',
+ vloc_varlist(1,5)='q ',vloc_varlist(2,5)='qg ',vloc_varlist(3,5)='q ',vloc_varlist(4,5)='qg ',
+ vloc_varlist(1,6)='sst',vloc_varlist(2,6)='ql ',vloc_varlist(3,6)='sst',vloc_varlist(4,6)='ql ',
+ vloc_varlist(1,7)='stl',vloc_varlist(2,7)='dbz',vloc_varlist(3,7)='stl',vloc_varlist(4,7)='dbz',
+ vloc_varlist(1,8)='sti',vloc_varlist(2,8)='aaa',vloc_varlist(3,8)='sti',vloc_varlist(4,8)='aaa',
/
&RAPIDREFRESH_CLDSURF
dfi_radar_latent_heat_time_period=20.0,
@@ -661,6 +527,8 @@ OBS_INPUT::
i_gsdqc=2,
/
&CHEM
+ laeroana_fv3smoke=.false.,
+ berror_fv3_cmaq_regional=.false.,
/
&NST
/
@@ -672,253 +540,50 @@ OBS_INPUT::
"
;;
- netcdf_fv3_regional)
+ hafs_envar)
-# Define namelist for netcdf fv3 run
+# Define namelist for hafs 3d hybrid envar run with global ensembles
export gsi_namelist="
&SETUP
- miter=2,niter(1)=50,niter(2)=50,niter_no_qc(1)=20,
+ miter=1,niter(1)=2,niter(2)=2,
+ niter_no_qc(1)=1,niter_no_qc(2)=0,
write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
qoption=2,
- factqmin=0.0,factqmax=0.0,deltim=$DELTIM,
+ gencode=78,deltim=1200,
+ factqmin=0.0,factqmax=0.0,
iguess=-1,
- newpc4pred=.true., adp_anglebc=.true., angord=4,
- diag_precon=.true., step_start=1.e-3,
- nhr_assimilation=3,l_foto=.false.,
- use_pbl=.false.,use_compress=.false.,gpstop=30.,
+ aircraft_recon=.true.,
+ oneobtest=.false.,retrieval=.false.,l_foto=.false.,
+ nhr_assimilation=6,
+ use_pbl=.true.,use_compress=.false.,nsig_ext=14,gpstop=50.,
+ use_gfs_nemsio=.false.,use_gfs_ncio=.true.,
+ print_diag_pcg=.true.,l2rwthin=.false.,hurricane_radar=.true.,
+ use_gfs_ozone=.false.,l4densvar=${l4densvar},nhr_obsbin=${nhr_obsbin},
lrun_subdirs=.true.,
- $SETUP
- /
- &GRIDOPTS
- fv3_regional=.true.,grid_ratio_fv3_regional=3.0,
- /
- &BKGERR
- hzscl=0.373,0.746,1.50,
- vs=0.6,bw=0.,fstat=.false.,
- /
- &ANBKGERR
- anisotropic=.false.,
- /
- &JCOPTS
- /
- &STRONGOPTS
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.true.,c_varqc=0.02,
- vadfile='prepbufr',oberrflg=.false.,njqc=.false.,vqc=.true.,
- /
- &OBS_INPUT
- dmesh(1)=120.0,dmesh(2)=60.0,dmesh(3)=60.0,dmesh(4)=60.0,dmesh(5)=120,time_window_max=1.5,ext_sonde=.true.,
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 0.0 0 0
- prepbufr t null t 0.0 0 0
- prepbufr q null q 0.0 0 0
- prepbufr pw null pw 0.0 0 0
- prepbufr uv null uv 0.0 0 0
- prepbufr spd null spd 0.0 0 0
- prepbufr dw null dw 0.0 0 0
- radarbufr rw null rw 0.0 0 0
- prepbufr sst null sst 0.0 0 0
- gpsrobufr gps_bnd null gps_bnd 0.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
- hirs2bufr hirs2 n14 hirs2_n14 0.0 1 0
- hirs3bufr hirs3 n16 hirs3_n16 0.0 1 0
- hirs3bufr hirs3 n17 hirs3_n17 0.0 1 0
- hirs4bufr hirs4 n18 hirs4_n18 0.0 1 0
- hirs4bufr hirs4 metop-a hirs4_metop-a 0.0 1 0
- hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 0
- gsndrbufr sndr g11 sndr_g11 0.0 1 0
- gsndrbufr sndr g12 sndr_g12 0.0 1 0
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs281_aqua 0.0 1 0
- msubufr msu n14 msu_n14 0.0 1 0
- amsuabufr amsua n15 amsua_n15 0.0 1 0
- amsuabufr amsua n16 amsua_n16 0.0 1 0
- amsuabufr amsua n17 amsua_n17 0.0 1 0
- amsuabufr amsua n18 amsua_n18 0.0 1 0
- amsuabufr amsua metop-a amsua_metop-a 0.0 1 0
- amsuabufr amsua metop-b amsua_metop-b 0.0 1 0
- airsbufr amsua aqua amsua_aqua 0.0 1 0
- amsubbufr amsub n15 amsub_n15 0.0 1 0
- amsubbufr amsub n16 amsub_n16 0.0 1 0
- amsubbufr amsub n17 amsub_n17 0.0 1 0
- mhsbufr mhs n18 mhs_n18 0.0 1 0
- mhsbufr mhs metop-a mhs_metop-a 0.0 1 0
- mhsbufr mhs metop-b mhs_metop-b 0.0 1 0
- ssmitbufr ssmi f13 ssmi_f13 0.0 1 0
- ssmitbufr ssmi f14 ssmi_f14 0.0 1 0
- ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_mid aqua amsre_aqua 0.0 1 0
- amsrebufr amsre_hig aqua amsre_aqua 0.0 1 0
- ssmisbufr ssmis f16 ssmis_f16 0.0 1 0
- iasibufr iasi metop-a iasi_metop-a 0.0 1 0
- gomebufr gome metop-a gome_metop-a 0.0 1 0
- iasibufr iasi metop-b iasi_metop-b 0.0 1 0
- omibufr omi aura omi_aura 0.0 1 0
- sbuvbufr sbuv2 n19 sbuv8_n19 0.0 1 0
- hirs4bufr hirs4 n19 hirs4_n19 0.0 1 0
- amsuabufr amsua n19 amsua_n19 0.0 1 0
- mhsbufr mhs n19 mhs_n19 0.0 1 0
- tcvitl tcp null tcp 0.0 0 0
- satwndbufr uv null uv 0.0 0 0
- atmsbufr atms npp atms_npp 0.0 1 0
- crisbufr cris npp cris_npp 0.0 1 0
- crisfsbufr cris-fsr npp cris-fsr_npp 0.0 1 0
- seviribufr seviri m08 seviri_m08 0.0 1 0
- seviribufr seviri m09 seviri_m09 0.0 1 0
- seviribufr seviri m10 seviri_m10 0.0 1 0
- seviribufr seviri m11 seviri_m11 0.0 1 0
- gsnd1bufr sndrd1 g15 sndrD1_g15 0.0 1 0
- gsnd1bufr sndrd2 g15 sndrD2_g15 0.0 1 0
- gsnd1bufr sndrd3 g15 sndrD3_g15 0.0 1 0
- gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 1 0
- prepbufr mta_cld null mta_cld 1.0 0 0
- prepbufr gos_ctp null gos_ctp 1.0 0 0
- lgycldbufr larccld null larccld 1.0 0 0
-::
- &SUPEROB_RADAR
- del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000.,
- l2superob_only=.false.,
- /
- &LAG_DATA
- /
- &HYBRID_ENSEMBLE
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- /
- &CHEM
- /
- &SINGLEOB_TEST
- /
- &NST
- /
-"
-;;
-
-cmaq_binary)
-
-# Define namelist for cmaq binary run
-
- export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=1,niter(2)=2,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- gencode=78,qoption=2,
- factqmin=0.0,factqmax=0.0,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,
- nhr_assimilation=3,l_foto=.false.,
- use_pbl=.false.,use_compress=.false.,
- diag_conv=.true.,lrun_subdirs=.true.,
- $SETUP
- /
- &GRIDOPTS
- JCAP=$JCAP,NLAT=$NLAT,NLON=$LONA,nsig=$LEVS,
- wrf_nmm_regional=.false.,wrf_mass_regional=.false.,
- cmaq_regional=.true.,diagnostic_reg=.true.,
- filled_grid=.false.,half_grid=.true.,netcdf=.false.,
- /
- &BKGERR
- hzscl=0.373,0.746,1.50,
- vs=1.0,bw=0.,fstat=.true.,
- /
- &ANBKGERR
- anisotropic=.false.,an_vs=1.0,ngauss=1,
- an_flen_u=-5.,an_flen_t=3.,an_flen_z=-200.,
- ifilt_ord=2,npass=3,normal=-200,grid_ratio=4.,nord_f2a=4,
- /
- &JCOPTS
- /
- &STRONGOPTS
- tlnmc_option=0,nstrong=0,nvmodes_keep=20,
- period_max=3.,baldiag_full=.true.,baldiag_inc=.true.,
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,noiqc=.true.,c_varqc=0.02,vadfile='prepbufr',njqc=.false.,vqc=.true.,
- /
- &OBS_INPUT
- dmesh(1)=120.0,dmesh(2)=60.0,dmesh(3)=60.0,dmesh(4)=60.0,
- dmesh(5)=120,time_window_max=1.5,
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- anowbufr pm2_5 null TEOM 1.0 0 0
-::
-!max name length for dfile=13
-!max name length for dtype=10
- &SUPEROB_RADAR
- del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000.,
- l2superob_only=.false.,
- /
- &LAG_DATA
- /
- &HYBRID_ENSEMBLE
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- /
- &CHEM
- berror_chem=.true.,
- oneobtest_chem=.false.,
- maginnov_chem=60,magoberr_chem=2.,oneob_type_chem='pm2_5',
- oblat_chem=45.,oblon_chem=270.,obpres_chem=1000.,
- diag_incr=.true.,elev_tolerance=500.,tunable_error=0.5,
- in_fname="\""${cmaq_input}"\"",out_fname="\""${cmaq_output}"\"",
- incr_fname="\""${chem_increment}"\"",
-!diag_incr for diagnostic increment output
- /
- &SINGLEOB_TEST
- maginnov=5,magoberr=0.1,oneob_type='t',
- oblat=45.,oblon=270.,obpres=1000.,obdattim=${adate},
- obhourset=0.,
- /
- &NST
- /
-"
-;;
-
-hwrf_nmm_d2)
-
-export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=1,niter(2)=2,niter_no_qc(1)=20,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- gencode=78,qoption=2,
- factqmin=0.0,factqmax=0.0,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,
- nhr_assimilation=6,l_foto=.false.,
- use_pbl=.true.,use_compress=.false.,
- print_diag_pcg=.true.,
- use_gfs_stratosphere=$USE_GFS_STRATOSPHERE,
- use_gfs_ozone=$USE_GFS_OZONE,
- regional_ozone=$REGIONAL_OZONE,
- nsig_ext=12,gpstop=50.,
- $SETUP
+ netcdf_diag=.true.,binary_diag=.false.,
+ newpc4pred=.true., adp_anglebc=.true., angord=4,
+ passive_bc=.false., use_edges=.false., emiss_bc=.true.,
+ diag_precon=.true., step_start=1.e-3, upd_pred(1)=0,
+ upd_pred(2)=0,upd_pred(3)=0,upd_pred(4)=0,
+ upd_pred(5)=0,upd_pred(6)=0,upd_pred(7)=0,
+ upd_pred(8)=0,upd_pred(9)=0,upd_pred(10)=0,
+ upd_pred(11)=0,upd_pred(12)=0,
+ lread_obs_save=.false.,
+ lread_obs_skip=.false.,
+ ens_nstarthr=6,
+ lwrite_predterms=.false.,lwrite_peakwt=.false.,reduce_diag=.false.,
/
&GRIDOPTS
- JCAP=$JCAP,JCAP_B=$JCAP_B,NLAT=$NLAT,NLON=$NLON,nsig=$LEVS,
- wrf_nmm_regional=.true.,wrf_mass_regional=.false.,
- diagnostic_reg=.true.,
- filled_grid=.false.,half_grid=.true.,netcdf=$NETCDF,
+ fv3_regional=.true.,grid_ratio_fv3_regional=1,nvege_type=20,
/
&BKGERR
- hzscl=0.25,0.5,1.0,
- vs=0.6,bw=0.,fstat=.false.,
- /
+ vs=1.0,
+ hzscl=0.2,0.4,0.8,
+ bw=0.,
+ fstat=.false.,
+/
&ANBKGERR
anisotropic=.false.,an_vs=1.0,ngauss=1,
an_flen_u=-5.,an_flen_t=3.,an_flen_z=-200.,
@@ -932,229 +597,210 @@ export gsi_namelist="
/
&OBSQC
dfact=0.75,dfact1=3.0,erradar_inflate=1.0,tdrerr_inflate=.true.,
- noiqc=.true.,c_varqc=0.02,vadfile='prepbufr',njqc=.false.,vqc=.true.,
+ noiqc=.true.,c_varqc=0.03333,vadfile='prepbufr',njqc=.false.,vqc=.true.,vadwnd_l2rw_qc=.false.,
+ q_doe_a_136=0.65,
+ q_doe_b_136=0.0003,
+ q_doe_a_137=0.75,
+ q_doe_b_137=0.0003,
+ t_doe_a_136=0.75,
+ t_doe_b_136=0.2,
+ t_doe_a_137=0.7,
+ t_doe_b_137=0.2,
+ uv_doe_a_236=0.5,
+ uv_doe_b_236=0.85,
+ uv_doe_a_237=0.5,
+ uv_doe_b_237=0.85,
+ uv_doe_a_213=0.4,
+ uv_doe_b_213=1.0,
/
&OBS_INPUT
- dmesh(1)=90.0,dmesh(2)=45.0,dmesh(3)=45.0,dmesh(4)=45.0,dmesh(5)=90,dmesh(7)=9.0,time_window_max=3.0,l_foreaft_thin=.false.,
+ dmesh(1)=90.0,dmesh(2)=45.0,dmesh(3)=45.0,dmesh(4)=45.0,dmesh(5)=90,time_window_max=3.0,l_foreaft_thin=.false.,
/
OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 0.0 0 0
- prepbufr t null t 0.0 0 0
- prepbufr q null q 0.0 0 0
- prepbufr pw null pw 0.0 0 0
- prepbufr uv null uv 0.0 0 0
- satwndbufr uv null uv 0.0 0 0
- prepbufr spd null spd 0.0 0 0
- prepbufr dw null dw 0.0 0 0
- radarbufr rw null rw 0.0 0 0
- prepbufr sst null sst 0.0 0 0
- tcvitl tcp null tcp 0.0 0 0
- tldplrbufr rw null rw 0.0 7 0
- hdobbufr uv null uv 0.0 0 0
- hdobbufr t null t 0.0 0 0
- hdobbufr q null q 0.0 0 0
- hdobbufr spd null spd 0.0 0 0
- gpsrobufr gps_bnd null gps 0.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
- hirs3bufr_skip hirs3 n17 hirs3_n17 0.0 1 0
- hirs4bufr hirs4 metop-a hirs4_metop-a 0.0 1 1
- gimgrbufr goes_img g11 imgr_g11 0.0 1 0
- gimgrbufr goes_img g12 imgr_g12 0.0 1 0
- airsbufr airs aqua airs_aqua 0.0 1 1
- amsuabufr_skip amsua n15 amsua_n15 0.0 2 1
- amsuabufr_skip amsua n18 amsua_n18 0.0 2 1
- amsuabufr amsua metop-a amsua_metop-a 0.0 2 1
- airsbufr_skip amsua aqua amsua_aqua 0.0 2 1
- amsubbufr amsub n17 amsub_n17 0.0 3 1
- mhsbufr_skip mhs n18 mhs_n18 0.0 3 1
- mhsbufr mhs metop-a mhs_metop-a 0.0 3 1
- ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
- amsrebufr amsre_low aqua amsre_aqua 0.0 4 0
- amsrebufr amsre_mid aqua amsre_aqua 0.0 4 0
- amsrebufr amsre_hig aqua amsre_aqua 0.0 4 0
- ssmisbufr ssmis f16 ssmis_f16 0.0 4 0
- ssmisbufr ssmis f17 ssmis_f17 0.0 4 0
- ssmisbufr ssmis f18 ssmis_f18 0.0 4 0
- ssmisbufr ssmis f19 ssmis_f19 0.0 4 0
- gsnd1bufr_skip sndrd1 g12 sndrD1_g12 0.0 5 0
- gsnd1bufr sndrd2 g12 sndrD2_g12 0.0 5 0
- gsnd1bufr_skip sndrd3 g12 sndrD3_g12 0.0 5 0
- gsnd1bufr_skip sndrd4 g12 sndrD4_g12 0.0 5 0
- gsnd1bufr_skip sndrd1 g11 sndrD1_g11 0.0 5 0
- gsnd1bufr_skip sndrd2 g11 sndrD2_g11 0.0 5 0
- gsnd1bufr_skip sndrd3 g11 sndrD3_g11 0.0 5 0
- gsnd1bufr_skip sndrd4 g11 sndrD4_g11 0.0 5 0
- gsnd1bufr_skip sndrd1 g13 sndrD1_g13 0.0 5 0
- gsnd1bufr_skip sndrd2 g13 sndrD2_g13 0.0 5 0
- gsnd1bufr_skip sndrd3 g13 sndrD3_g13 0.0 5 0
- gsnd1bufr_skip sndrd4 g13 sndrD4_g13 0.0 5 0
- iasibufr iasi metop-a iasi_metop-a 0.0 1 1
- gomebufr gome metop-a gome_metop-a 0.0 2 0
- omibufr omi aura omi_aura 0.0 2 0
- sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
- hirs4bufr hirs4 n19 hirs4_n19 0.0 1 1
- amsuabufr amsua n19 amsua_n19 0.0 2 1
- mhsbufr mhs n19 mhs_n19 0.0 3 1
- seviribufr seviri m08 seviri_m08 0.0 1 0
- seviribufr seviri m09 seviri_m09 0.0 1 0
- seviribufr seviri m10 seviri_m10 0.0 1 0
- seviribufr seviri m11 seviri_m11 0.0 1 0
- hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 0
- amsuabufr amsua metop-b amsua_metop-b 0.0 2 0
- mhsbufr mhs metop-b mhs_metop-b 0.0 3 0
- iasibufr iasi metop-b iasi_metop-b 0.0 1 0
- gomebufr gome metop-b gome_metop-b 0.0 2 0
- atmsbufr atms npp atms_npp 0.0 2 0
- atmsbufr atms n20 atms_n20 0.0 2 0
- crisbufr cris npp cris_npp 0.0 1 0
- crisfsbufr cris-fsr npp cris-fsr_npp 0.0 1 0
- crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 1 0
- gsnd1bufr sndrd1 g14 sndrD1_g14 0.0 5 0
- gsnd1bufr sndrd2 g14 sndrD2_g14 0.0 5 0
- gsnd1bufr sndrd3 g14 sndrD3_g14 0.0 5 0
- gsnd1bufr sndrd4 g14 sndrD4_g14 0.0 5 0
- gsnd1bufr sndrd1 g15 sndrD1_g15 0.0 5 0
- gsnd1bufr sndrd2 g15 sndrD2_g15 0.0 5 0
- gsnd1bufr sndrd3 g15 sndrD3_g15 0.0 5 0
- gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 5 0
- ompsnpbufr ompsnp npp ompsnp_npp 0.0 0 0
- ompstcbufr ompstc8 npp ompstc8_npp 0.0 2 0
+! dfile dtype dplat dsis dval dthin dsfcalc
+ prepbufr ps null ps 0.0 0 0
+ prepbufr t null t 0.0 0 0
+ prepbufr_profl t null t 0.0 0 0
+ prepbufr q null q 0.0 0 0
+ prepbufr_profl q null q 0.0 0 0
+ prepbufr pw null pw 0.0 0 0
+ prepbufr uv null uv 0.0 0 0
+ prepbufr_profl uv null uv 0.0 0 0
+ satwndbufr uv null uv 0.0 0 0
+ satwhrbufr uv null uv 0.0 0 0
+ prepbufr spd null spd 0.0 0 0
+ prepbufr dw null dw 0.0 0 0
+ radarbufr rw null rw 0.0 0 0
+ prepbufr sst null sst 0.0 0 0
+ tcvitl tcp null tcp 0.0 0 0
+ tldplrbufr rw null rw 0.0 0 0
+ l2rwbufr rw null l2rw 0.0 0 0
+ hdobbufr uv null uv 0.0 0 0
+ hdobbufr t null t 0.0 0 0
+ hdobbufr q null q 0.0 0 0
+ hdobbufr spd null spd 0.0 0 0
+ gpsrobufr gps_bnd null gps 0.0 0 0
+ ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
+ tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
+ sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
+ sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
+ sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
+ gimgrbufr goes_img g11 imgr_g11 0.0 1 0
+ gimgrbufr goes_img g12 imgr_g12 0.0 1 0
+ airsbufr airs aqua airs_aqua 0.0 1 1
+ amsuabufr amsua n15 amsua_n15 0.0 2 1
+ amsuabufr amsua n18 amsua_n18 0.0 2 1
+ amsuabufr amsua metop-a amsua_metop-a 0.0 2 1
+ airsbufr amsua aqua amsua_aqua 0.0 2 1
+ amsubbufr amsub n17 amsub_n17 0.0 3 1
+ mhsbufr mhs n18 mhs_n18 0.0 3 1
+ mhsbufr mhs metop-a mhs_metop-a 0.0 3 1
+ ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
+ amsrebufr amsre_low aqua amsre_aqua 0.0 4 0
+ amsrebufr amsre_mid aqua amsre_aqua 0.0 4 0
+ amsrebufr amsre_hig aqua amsre_aqua 0.0 4 0
+ ssmisbufr ssmis f16 ssmis_f16 0.0 4 0
+ ssmisbufr ssmis f17 ssmis_f17 0.0 4 0
+ ssmisbufr ssmis f18 ssmis_f18 0.0 4 0
+ ssmisbufr ssmis f19 ssmis_f19 0.0 4 0
+ gsnd1bufr sndrd1 g12 sndrD1_g12 0.0 5 0
+ gsnd1bufr sndrd2 g12 sndrD2_g12 0.0 5 0
+ gsnd1bufr sndrd3 g12 sndrD3_g12 0.0 5 0
+ gsnd1bufr sndrd4 g12 sndrD4_g12 0.0 5 0
+ gsnd1bufr sndrd1 g11 sndrD1_g11 0.0 5 0
+ gsnd1bufr sndrd2 g11 sndrD2_g11 0.0 5 0
+ gsnd1bufr sndrd3 g11 sndrD3_g11 0.0 5 0
+ gsnd1bufr sndrd4 g11 sndrD4_g11 0.0 5 0
+ gsnd1bufr sndrd1 g13 sndrD1_g13 0.0 5 0
+ gsnd1bufr sndrd2 g13 sndrD2_g13 0.0 5 0
+ gsnd1bufr sndrd3 g13 sndrD3_g13 0.0 5 0
+ gsnd1bufr sndrd4 g13 sndrD4_g13 0.0 5 0
+ iasibufr iasi metop-a iasi_metop-a 0.0 1 1
+ gomebufr gome metop-a gome_metop-a 0.0 2 0
+ omibufr omi aura omi_aura 0.0 2 0
+ sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
+ amsuabufr amsua n19 amsua_n19 0.0 2 1
+ mhsbufr mhs n19 mhs_n19 0.0 3 1
+ seviribufr seviri m08 seviri_m08 0.0 1 0
+ seviribufr seviri m09 seviri_m09 0.0 1 0
+ seviribufr seviri m10 seviri_m10 0.0 1 0
+ amsuabufr amsua metop-b amsua_metop-b 0.0 2 0
+ mhsbufr mhs metop-b mhs_metop-b 0.0 3 0
+ iasibufr iasi metop-b iasi_metop-b 0.0 1 0
+ gomebufr gome metop-b gome_metop-b 0.0 2 0
+ atmsbufr atms npp atms_npp 0.0 2 0
+ atmsbufr atms n20 atms_n20 0.0 2 0
+ crisbufr cris npp cris_npp 0.0 1 0
+ crisfsbufr cris-fsr npp cris-fsr_npp 0.0 1 0
+ crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 1 0
+ gsnd1bufr sndrd1 g14 sndrD1_g14 0.0 5 0
+ gsnd1bufr sndrd2 g14 sndrD2_g14 0.0 5 0
+ gsnd1bufr sndrd3 g14 sndrD3_g14 0.0 5 0
+ gsnd1bufr sndrd4 g14 sndrD4_g14 0.0 5 0
+ gsnd1bufr sndrd1 g15 sndrD1_g15 0.0 5 0
+ gsnd1bufr sndrd2 g15 sndrD2_g15 0.0 5 0
+ gsnd1bufr sndrd3 g15 sndrD3_g15 0.0 5 0
+ gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 5 0
+ oscatbufr uv null uv 0.0 0 0
+ mlsbufr mls30 aura mls30_aura 0.0 0 0
+ amsr2bufr amsr2 gcom-w1 amsr2_gcom-w1 0.0 3 0
+ gmibufr gmi gpm gmi_gpm 0.0 3 0
+ saphirbufr saphir meghat saphir_meghat 0.0 3 0
+ ahibufr ahi himawari8 ahi_himawari8 0.0 3 0
::
&SUPEROB_RADAR
- del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000.,
- l2superob_only=.false.,
- /
+ del_azimuth=5.,del_elev=.25,del_range=10000.,del_time=1.0,elev_angle_max=5.,minnum=1,range_max=200000.,
+ l2superob_only=.false.,radar_sites=.false.,
+ radar_box=.true.,radar_rmesh=10,radar_zmesh=500,
+ /
+SUPEROB_RADAR::
+ KBRO 1
+ KCRP 1
+ KEWX 1
+ KGRX 1
+ KDFX 1
+ KHGX 1
+ KLCH 1
+ KLIX 1
+ KPOE 1
+ KSHV 1
+ KDGX 1
+ KMOB 1
+ KEVX 1
+ KEOX 1
+ KMXX 1
+ KBMX 1
+ KTLH 1
+ KTBW 1
+ KBYX 1
+ KAMX 1
+ KMLB 1
+ KJAX 1
+ KVAX 1
+ KJGX 1
+ KFFC 1
+ KCLX 1
+ KCAE 1
+ KGSP 1
+ KLTX 1
+ KMHX 1
+ KRAX 1
+ KAKQ 1
+ KFCX 1
+ KLWX 1
+ KDOX 1
+ KCCX 1
+ KDIX 1
+ KOKX 1
+ KENX 1
+ KBGM 1
+ KCXX 1
+ KBOX 1
+ KGYX 1
+ KCBW 1
+ TJUA 1
+ PHWA 1
+ PHKI 1
+ PHMO 1
+ PHKM 1
+::
+/
&LAG_DATA
/
&HYBRID_ENSEMBLE
- l_hyb_ens=.true.,n_ens=10,uv_hyb_ens=.true.,beta_s0=0.2,
- readin_beta=.true.,
- s_ens_h=300,s_ens_v=-0.5,readin_localization=.false.,
- generate_ens=.false.,regional_ensemble_option=1,grid_ratio_ens=1,
- pseudo_hybens=.false.,merge_two_grid_ensperts=.false.,
- pwgtflg=.false.,aniso_a_en=.false.,
- nlon_ens=165,nlat_ens=335,jcap_ens=0,jcap_ens_test=0,
+ l_hyb_ens=.true.,
+ n_ens=${N_ENS},
+ uv_hyb_ens=.true.,
+ beta_s0=${BETA_S0},
+ s_ens_h=150,
+ s_ens_v=-0.5,
+ readin_localization=.false.,
+ generate_ens=.false.,
+ regional_ensemble_option=${REGIONAL_ENSEMBLE_OPTION},
+ grid_ratio_ens=${GRID_RATIO_ENS},
+ pseudo_hybens=.false.,
+ merge_two_grid_ensperts=F,
+ pwgtflg=F,
+ aniso_a_en=.false.,
+ nlon_ens=387,
+ nlat_ens=777,
+ write_ens_sprd=F,
+ l_both_fv3sar_gfs_ens=${l_both_fv3sar_gfs_ens},
+ n_ens_gfs=${n_ens_gfs},
+ n_ens_fv3sar=${n_ens_fv3sar},
/
&RAPIDREFRESH_CLDSURF
dfi_radar_latent_heat_time_period=30.0,
/
&CHEM
/
- &SINGLEOB_TEST
- maginnov=1.0,magoberr=0.8,oneob_type='t',
- oblat=38.,oblon=279.,obpres=500.,obdattim=${adate},
- obhourset=0.,
- /
&NST
/
-"
-;;
-
-hwrf_nmm_d3)
-
-export gsi_namelist="
-
- &SETUP
- miter=2,niter(1)=1,niter(2)=2,niter_no_qc(1)=20,
- write_diag(1)=.true.,write_diag(2)=.false.,write_diag(3)=.true.,
- gencode=78,qoption=2,
- factqmin=0.0,factqmax=0.0,deltim=$DELTIM,
- iguess=-1,
- oneobtest=.false.,retrieval=.false.,
- nhr_assimilation=6,l_foto=.false.,
- use_pbl=.true.,use_compress=.false.,
- print_diag_pcg=.true.,
- use_gfs_stratosphere=$USE_GFS_STRATOSPHERE,
- use_gfs_ozone=$USE_GFS_OZONE,
- regional_ozone=$REGIONAL_OZONE,
- nsig_ext=12,gpstop=50.,
- $SETUP
- /
- &GRIDOPTS
- JCAP=$JCAP,JCAP_B=$JCAP_B,NLAT=$NLAT,NLON=$NLON,nsig=$LEVS,
- wrf_nmm_regional=.true.,wrf_mass_regional=.false.,
- diagnostic_reg=.true.,
- filled_grid=.false.,half_grid=.true.,netcdf=$NETCDF,
- /
- &BKGERR
- hzscl=0.2,0.4,0.8,
- vs=0.6,bw=0.,fstat=.false.,
- /
- &ANBKGERR
- anisotropic=.false.,an_vs=1.0,ngauss=1,
- an_flen_u=-5.,an_flen_t=3.,an_flen_z=-200.,
- ifilt_ord=2,npass=3,normal=-200,grid_ratio=4.,nord_f2a=4,
- /
- &JCOPTS
- /
- &STRONGOPTS
- tlnmc_option=0,reg_tlnmc_type=1,nstrong=1,nvmodes_keep=8,period_max=6.,
- period_width=1.5,baldiag_full=.false.,baldiag_inc=.false.,
- /
- &OBSQC
- dfact=0.75,dfact1=3.0,erradar_inflate=1.0,tdrerr_inflate=.true.,
- noiqc=.true.,c_varqc=0.02,vadfile='prepbufr',njqc=.false.,vqc=.true.,
- /
- &OBS_INPUT
- dmesh(1)=90.0,dmesh(2)=45.0,dmesh(3)=45.0,dmesh(4)=45.0,dmesh(5)=90,dmesh(7)=9.0,time_window_max=3.0,l_foreaft_thin=.false.,
- /
-OBS_INPUT::
-! dfile dtype dplat dsis dval dthin dsfcalc
- prepbufr ps null ps 0.0 0 0
- prepbufr t null t 0.0 0 0
- prepbufr q null q 0.0 0 0
- prepbufr pw null pw 0.0 0 0
- prepbufr uv null uv 0.0 0 0
- satwndbufr uv null uv 0.0 0 0
- prepbufr spd null spd 0.0 0 0
- prepbufr dw null dw 0.0 0 0
- radarbufr rw null rw 0.0 0 0
- prepbufr sst null sst 0.0 0 0
- tcvitl tcp null tcp 0.0 0 0
- tldplrbufr rw null rw 0.0 7 0
- hdobbufr uv null uv 0.0 0 0
- hdobbufr t null t 0.0 0 0
- hdobbufr q null q 0.0 0 0
- hdobbufr spd null spd 0.0 0 0
- gpsrobufr gps_bnd null gps 0.0 0 0
- ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
- tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
- sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
- sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
- sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
-::
- &SUPEROB_RADAR
- del_azimuth=5.,del_elev=.25,del_range=5000.,del_time=.5,elev_angle_max=5.,minnum=50,range_max=100000.,
- l2superob_only=.false.,
- /
- &LAG_DATA
- /
- &HYBRID_ENSEMBLE
- l_hyb_ens=.true.,n_ens=10,uv_hyb_ens=.true.,beta_s0=0.2,
- readin_beta=.true.,
- s_ens_h=150,s_ens_v=-0.5,readin_localization=.false.,
- generate_ens=.false.,regional_ensemble_option=1,grid_ratio_ens=1,
- pseudo_hybens=.false.,merge_two_grid_ensperts=.false.,
- pwgtflg=.false.,aniso_a_en=.false.,
- nlon_ens=249,nlat_ens=499,jcap_ens=0,jcap_ens_test=0,
- /
- &RAPIDREFRESH_CLDSURF
- dfi_radar_latent_heat_time_period=30.0,
- /
- &CHEM
- /
&SINGLEOB_TEST
maginnov=1.0,magoberr=0.8,oneob_type='t',
- oblat=38.,oblon=279.,obpres=500.,obdattim=${adate},
+ oblat=38.,oblon=279.,obpres=500.,obdattim=2020040500,
obhourset=0.,
/
- &NST
- /
"
;;
diff --git a/regression/regression_param.sh b/regression/regression_param.sh
index 85f2949bfe..bfc6f042fc 100755
--- a/regression/regression_param.sh
+++ b/regression/regression_param.sh
@@ -9,15 +9,25 @@ case $machine in
memnode=96
numcore=40
;;
- Orion)
+ Orion)
sub_cmd="sub_orion"
memnode=192
numcore=40
+ ;;
+ Hercules)
+ sub_cmd="sub_hercules"
+ memnode=512
+ numcore=40
;;
Jet)
sub_cmd="sub_jet"
memnode=96
numcore=40
+ ;;
+ Gaea)
+ sub_cmd="sub_gaea"
+ memnode=251
+ numcore=128
;;
wcoss2)
sub_cmd="sub_wcoss2"
@@ -26,9 +36,6 @@ case $machine in
;;
Discover)
sub_cmd="sub_discover"
- ;;
- Cheyenne)
- sub_cmd="sub_ncar -a p48503002 -q economy -d $PWD"
;;
*) # EXIT out for unresolved machine
echo "unknown $machine"
@@ -44,144 +51,148 @@ export maxmem=$((($memnode*1024*1024)/$numcore)) # Kb / core
case $regtest in
- global_3dvar)
+ global_4denvar)
if [[ "$machine" = "Hera" ]]; then
- topts[1]="0:15:00" ; popts[1]="12/5/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="12/9/" ; ropts[2]="/2"
+ topts[1]="0:10:00" ; popts[1]="12/8/" ; ropts[1]="/1"
+ topts[2]="0:10:00" ; popts[2]="12/10/" ; ropts[2]="/2"
elif [[ "$machine" = "Orion" ]]; then
- topts[1]="0:15:00" ; popts[1]="12/5/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="12/9/" ; ropts[2]="/2"
+ topts[1]="0:10:00" ; popts[1]="12/8/" ; ropts[1]="/1"
+ topts[2]="0:10:00" ; popts[2]="12/12/" ; ropts[2]="/2"
+ elif [[ "$machine" = "Hercules" ]]; then
+ topts[1]="0:10:00" ; popts[1]="12/8/" ; ropts[1]="/1"
+ topts[2]="0:10:00" ; popts[2]="12/12/" ; ropts[2]="/2"
elif [[ "$machine" = "Jet" ]]; then
- topts[1]="0:50:00" ; popts[1]="12/3/" ; ropts[1]="/1"
- topts[2]="0:50:00" ; popts[2]="12/9/" ; ropts[2]="/2"
- elif [[ "$machine" = "Cheyenne" ]]; then
- topts[1]="0:30:00" ; popts[1]="16/2/" ; ropts[1]="/1"
- topts[2]="0:30:00" ; popts[2]="16/4/" ; ropts[2]="/2"
- elif [[ "$machine" = "wcoss2" ]]; then
- topts[1]="0:15:00" ; popts[1]="12/5/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="12/9/" ; ropts[2]="/2"
+ topts[1]="0:10:00" ; popts[1]="12/8/" ; ropts[1]="/1"
+ topts[2]="0:10:00" ; popts[2]="12/10/" ; ropts[2]="/2"
elif [[ "$machine" = "Discover" ]]; then
- topts[1]="0:30:00" ; popts[1]="36/2" ; ropts[1]="/1"
- topts[2]="0:30:00" ; popts[2]="72/3" ; ropts[2]="/2"
+ topts[1]="0:30:00" ; popts[1]="48/2" ; ropts[1]="/1"
+ topts[2]="0:30:00" ; popts[2]="60/3" ; ropts[2]="/2"
+ elif [[ "$machine" = "Gaea" ]]; then
+ topts[1]="0:10:00" ; popts[1]="12/8/" ; ropts[1]="/1"
+ topts[2]="0:10:00" ; popts[2]="12/10/" ; ropts[2]="/2"
+ elif [[ "$machine" = "wcoss2" ]]; then
+ topts[1]="0:10:00" ; popts[1]="12/8/" ; ropts[1]="/1"
+ topts[2]="0:10:00" ; popts[2]="12/10/" ; ropts[2]="/2"
fi
if [ "$debug" = ".true." ] ; then
- topts[1]="0:45:00"
+ topts[1]="1:30:00"
fi
scaling[1]=10; scaling[2]=8; scaling[3]=4
;;
- global_4dvar)
+ rrfs_3denvar_rdasens)
if [[ "$machine" = "Hera" ]]; then
- topts[1]="0:15:00" ; popts[1]="12/3/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="12/5/" ; ropts[2]="/2"
+ topts[1]="0:05:00" ; popts[1]="40/3/" ; ropts[1]="/1"
+ topts[2]="0:05:00" ; popts[2]="40/5/" ; ropts[2]="/1"
elif [[ "$machine" = "Orion" ]]; then
- topts[1]="0:15:00" ; popts[1]="12/3/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="12/5/" ; ropts[2]="/2"
+ topts[1]="0:15:00" ; popts[1]="5/4/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="10/4/" ; ropts[2]="/2"
+ elif [[ "$machine" = "Hercules" ]]; then
+ topts[1]="0:05:00" ; popts[1]="40/3/" ; ropts[1]="/1"
+ topts[2]="0:05:00" ; popts[2]="40/5/" ; ropts[2]="/2"
elif [[ "$machine" = "Jet" ]]; then
- topts[1]="0:15:00" ; popts[1]="12/3/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="12/5/" ; ropts[2]="/2"
- elif [[ "$machine" = "Cheyenne" ]]; then
- topts[1]="0:35:00" ; popts[1]="16/2/" ; ropts[1]="/1"
- topts[2]="0:25:00" ; popts[2]="16/4/" ; ropts[2]="/2"
+ topts[1]="0:15:00" ; popts[1]="5/4/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="10/4/" ; ropts[2]="/1"
+ elif [[ "$machine" = "Gaea" ]]; then
+ topts[1]="0:15:00" ; popts[1]="64/1/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="128/2/" ; ropts[2]="/1"
elif [[ "$machine" = "wcoss2" ]]; then
- topts[1]="0:15:00" ; popts[1]="28/2/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="28/4/" ; ropts[2]="/2"
- elif [[ "$machine" = "Discover" ]]; then
- topts[1]="2:00:00" ; popts[1]="48/2" ; ropts[1]="/1"
- topts[2]="2:00:00" ; popts[2]="60/3" ; ropts[2]="/2"
+ topts[1]="0:15:00" ; popts[1]="64/1/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="128/2/" ; ropts[2]="/1"
fi
if [ "$debug" = ".true." ] ; then
- topts[1]="0:45:00"
- if [[ "$machine" = "Hera" ]]; then
- popts[1]="12/5/"
- elif [[ "$machine" = "Orion" ]]; then
- popts[1]="12/5/"
- elif [[ "$machine" = "Jet" ]]; then
- popts[1]="12/5/"
- elif [[ "$machine" = "wcoss2" ]]; then
- popts[1]="28/4/"
- topts[1]="3:00:00"
- fi
+ topts[1]="0:30:00"
fi
- scaling[1]=5; scaling[2]=8; scaling[3]=2
+ scaling[1]=2; scaling[2]=10; scaling[3]=4
;;
- global_4denvar)
+ hafs_3denvar_hybens)
if [[ "$machine" = "Hera" ]]; then
- topts[1]="0:10:00" ; popts[1]="12/8/" ; ropts[1]="/1"
- topts[2]="0:10:00" ; popts[2]="12/10/" ; ropts[2]="/2"
+ topts[1]="0:15:00" ; popts[1]="5/4/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="10/4/" ; ropts[2]="/1"
elif [[ "$machine" = "Orion" ]]; then
- topts[1]="0:10:00" ; popts[1]="12/8/" ; ropts[1]="/1"
- topts[2]="0:10:00" ; popts[2]="12/12/" ; ropts[2]="/2"
+ topts[1]="0:15:00" ; popts[1]="5/4/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="10/4/" ; ropts[2]="/2"
+ elif [[ "$machine" = "Hercules" ]]; then
+ topts[1]="0:15:00" ; popts[1]="20/1/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="5/8/" ; ropts[2]="/2"
elif [[ "$machine" = "Jet" ]]; then
- topts[1]="0:35:00" ; popts[1]="6/8/" ; ropts[1]="/1"
- topts[2]="0:35:00" ; popts[2]="6/10/" ; ropts[2]="/2"
- elif [[ "$machine" = "Discover" ]]; then
- topts[1]="0:30:00" ; popts[1]="48/2" ; ropts[1]="/1"
- topts[2]="0:30:00" ; popts[2]="60/3" ; ropts[2]="/2"
- elif [[ "$machine" = "Cheyenne" ]]; then
- topts[1]="1:59:00" ; popts[1]="6/8/" ; ropts[1]="/1"
- topts[2]="0:35:00" ; popts[2]="6/10/" ; ropts[2]="/2"
+ topts[1]="0:15:00" ; popts[1]="5/4/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="10/4/" ; ropts[2]="/1"
+ elif [[ "$machine" = "Gaea" ]]; then
+ topts[1]="0:15:00" ; popts[1]="64/1/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="128/2/" ; ropts[2]="/1"
elif [[ "$machine" = "wcoss2" ]]; then
- topts[1]="0:10:00" ; popts[1]="12/8/" ; ropts[1]="/1"
- topts[2]="0:10:00" ; popts[2]="12/10/" ; ropts[2]="/2"
+ topts[1]="0:15:00" ; popts[1]="64/1/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="128/2/" ; ropts[2]="/1"
fi
if [ "$debug" = ".true." ] ; then
- topts[1]="1:30:00"
+ topts[1]="0:30:00"
fi
- scaling[1]=10; scaling[2]=8; scaling[3]=4
+ scaling[1]=2; scaling[2]=10; scaling[3]=4
;;
- rrfs_3denvar_glbens)
-
+ hafs_4denvar_glbens)
if [[ "$machine" = "Hera" ]]; then
- topts[1]="0:15:00" ; popts[1]="20/1/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="20/2/" ; ropts[2]="/1"
+ topts[1]="0:15:00" ; popts[1]="5/4/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="10/4/" ; ropts[2]="/1"
elif [[ "$machine" = "Orion" ]]; then
- topts[1]="0:15:00" ; popts[1]="4/4/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="6/6/" ; ropts[2]="/1"
+ topts[1]="0:20:00" ; popts[1]="5/4/" ; ropts[1]="/1"
+ topts[2]="0:20:00" ; popts[2]="20/2/" ; ropts[2]="/1"
+ elif [[ "$machine" = "Hercules" ]]; then
+ topts[1]="0:20:00" ; popts[1]="5/4/" ; ropts[1]="/1"
+ topts[2]="0:20:00" ; popts[2]="10/4/" ; ropts[2]="/1"
elif [[ "$machine" = "Jet" ]]; then
- topts[1]="0:15:00" ; popts[1]="4/4/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="6/6/" ; ropts[2]="/1"
+ topts[1]="0:15:00" ; popts[1]="5/4/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="10/4/" ; ropts[2]="/1"
+ elif [[ "$machine" = "Gaea" ]]; then
+ topts[1]="0:15:00" ; popts[1]="64/1/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="128/2/" ; ropts[2]="/1"
elif [[ "$machine" = "wcoss2" ]]; then
topts[1]="0:15:00" ; popts[1]="64/1/" ; ropts[1]="/1"
topts[2]="0:15:00" ; popts[2]="128/2/" ; ropts[2]="/1"
fi
if [ "$debug" = ".true." ] ; then
- topts[1]="0:30:00"
+ topts[1]="0:45:00"
fi
- scaling[1]=2; scaling[2]=10; scaling[3]=4
+ scaling[1]=10; scaling[2]=8; scaling[3]=4
;;
- netcdf_fv3_regional)
+ rrfs_enkf_conv)
if [[ "$machine" = "Hera" ]]; then
- topts[1]="0:15:00" ; popts[1]="4/4/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="6/6/" ; ropts[2]="/1"
+ topts[1]="0:05:00" ; popts[1]="40/2/" ; ropts[1]="/1"
+ topts[2]="0:05:00" ; popts[2]="40/4/" ; ropts[2]="/1"
elif [[ "$machine" = "Orion" ]]; then
- topts[1]="0:15:00" ; popts[1]="4/4/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="6/6/" ; ropts[2]="/1"
+ topts[1]="0:15:00" ; popts[1]="4/4/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="6/6/" ; ropts[2]="/1"
+ elif [[ "$machine" = "Hercules" ]]; then
+ topts[1]="0:05:00" ; popts[1]="40/2/" ; ropts[1]="/1"
+ topts[2]="0:05:00" ; popts[2]="40/4/" ; ropts[2]="/1"
elif [[ "$machine" = "Jet" ]]; then
- topts[1]="0:15:00" ; popts[1]="4/4/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="6/6/" ; ropts[2]="/1"
+ topts[1]="0:15:00" ; popts[1]="4/4/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="6/6/" ; ropts[2]="/1"
+ elif [[ "$machine" = "Gaea" ]]; then
+ topts[1]="0:15:00" ; popts[1]="28/1/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="28/2/" ; ropts[2]="/1"
elif [[ "$machine" = "wcoss2" ]]; then
- topts[1]="0:15:00" ; popts[1]="28/1/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="28/2/" ; ropts[2]="/1"
+ topts[1]="0:15:00" ; popts[1]="64/1/" ; ropts[1]="/1"
+ topts[2]="0:15:00" ; popts[2]="64/2/" ; ropts[2]="/1"
fi
if [ "$debug" = ".true." ] ; then
@@ -195,17 +206,20 @@ case $regtest in
rtma)
if [[ "$machine" = "Hera" ]]; then
- topts[1]="0:30:00" ; popts[1]="6/12/" ; ropts[1]="/1"
- topts[2]="0:30:00" ; popts[2]="8/12/" ; ropts[2]="/1"
+ topts[1]="0:30:00" ; popts[1]="6/12/" ; ropts[1]="/1"
+ topts[2]="0:30:00" ; popts[2]="8/12/" ; ropts[2]="/1"
elif [[ "$machine" = "Orion" ]]; then
- topts[1]="0:30:00" ; popts[1]="6/12/" ; ropts[1]="/1"
- topts[2]="0:30:00" ; popts[2]="8/12/" ; ropts[2]="/1"
+ topts[1]="0:30:00" ; popts[1]="6/12/" ; ropts[1]="/1"
+ topts[2]="0:30:00" ; popts[2]="8/12/" ; ropts[2]="/1"
+ elif [[ "$machine" = "Hercules" ]]; then
+ topts[1]="0:30:00" ; popts[1]="6/12/" ; ropts[1]="/1"
+ topts[2]="0:30:00" ; popts[2]="8/12/" ; ropts[2]="/1"
elif [[ "$machine" = "Jet" ]]; then
- topts[1]="0:30:00" ; popts[1]="6/12/" ; ropts[1]="/1"
- topts[2]="0:30:00" ; popts[2]="8/12/" ; ropts[2]="/1"
- elif [[ "$machine" = "Cheyenne" ]]; then
- topts[1]="0:15:00" ; popts[1]="8/6/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="8/8/" ; ropts[2]="/1"
+ topts[1]="0:30:00" ; popts[1]="6/12/" ; ropts[1]="/1"
+ topts[2]="0:30:00" ; popts[2]="8/12/" ; ropts[2]="/1"
+ elif [[ "$machine" = "Gaea" ]]; then
+ topts[1]="0:30:00" ; popts[1]="14/8/" ; ropts[1]="/1"
+ topts[2]="0:30:00" ; popts[2]="14/14/" ; ropts[2]="/1"
elif [[ "$machine" = "wcoss2" ]]; then
topts[1]="0:30:00" ; popts[1]="14/8/" ; ropts[1]="/1"
topts[2]="0:30:00" ; popts[2]="14/14/" ; ropts[2]="/2"
@@ -219,47 +233,23 @@ case $regtest in
;;
- hwrf_nmm_d2 | hwrf_nmm_d3)
-
- if [[ "$machine" = "Hera" ]]; then
- topts[1]="0:20:00" ; popts[1]="6/6/" ; ropts[1]="/1"
- topts[2]="0:20:00" ; popts[2]="8/8/" ; ropts[2]="/1"
- elif [[ "$machine" = "Orion" ]]; then
- topts[1]="0:20:00" ; popts[1]="6/6/" ; ropts[1]="/1"
- topts[2]="0:20:00" ; popts[2]="8/8/" ; ropts[2]="/1"
- elif [[ "$machine" = "Jet" ]]; then
- topts[1]="0:20:00" ; popts[1]="6/6/" ; ropts[1]="/1"
- topts[2]="0:20:00" ; popts[2]="8/8/" ; ropts[2]="/1"
- elif [[ "$machine" = "Cheyenne" ]]; then
- topts[1]="0:20:00" ; popts[1]="6/6/" ; ropts[1]="/1"
- topts[2]="0:20:00" ; popts[2]="8/8/" ; ropts[2]="/1"
- elif [[ "$machine" = "wcoss2" ]]; then
- topts[1]="0:15:00" ; popts[1]="10/10/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="14/14/" ; ropts[2]="/2"
- fi
-
- if [ "$debug" = ".true." ] ; then
- topts[1]="1:00:00"
- fi
-
- scaling[1]=5; scaling[2]=10; scaling[3]=2
-
- ;;
-
global_enkf)
if [[ "$machine" = "Hera" ]]; then
- topts[1]="0:10:00" ; popts[1]="12/3/" ; ropts[1]="/1"
- topts[2]="0:10:00" ; popts[2]="12/5/" ; ropts[2]="/2"
+ topts[1]="0:10:00" ; popts[1]="12/3/" ; ropts[1]="/1"
+ topts[2]="0:10:00" ; popts[2]="12/5/" ; ropts[2]="/2"
elif [[ "$machine" = "Orion" ]]; then
- topts[1]="0:10:00" ; popts[1]="12/3/" ; ropts[1]="/1"
- topts[2]="0:10:00" ; popts[2]="12/5/" ; ropts[2]="/2"
+ topts[1]="0:10:00" ; popts[1]="12/3/" ; ropts[1]="/1"
+ topts[2]="0:10:00" ; popts[2]="12/5/" ; ropts[2]="/2"
+ elif [[ "$machine" = "Hercules" ]]; then
+ topts[1]="0:10:00" ; popts[1]="12/3/" ; ropts[1]="/1"
+ topts[2]="0:10:00" ; popts[2]="12/5/" ; ropts[2]="/2"
elif [[ "$machine" = "Jet" ]]; then
- topts[1]="0:15:00" ; popts[1]="12/3/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="12/5/" ; ropts[2]="/2"
- elif [[ "$machine" = "Cheyenne" ]]; then
- topts[1]="0:15:00" ; popts[1]="16/2/" ; ropts[1]="/1"
- topts[2]="0:15:00" ; popts[2]="16/4/" ; ropts[2]="/2"
+ topts[1]="0:10:00" ; popts[1]="12/3/" ; ropts[1]="/1"
+ topts[2]="0:10:00" ; popts[2]="12/5/" ; ropts[2]="/2"
+ elif [[ "$machine" = "Gaea" ]]; then
+ topts[1]="0:10:00" ; popts[1]="16/2/" ; ropts[1]="/1"
+ topts[2]="0:10:00" ; popts[2]="16/4/" ; ropts[2]="/2"
elif [[ "$machine" = "wcoss2" ]]; then
topts[1]="0:10:00" ; popts[1]="16/2/" ; ropts[1]="/1"
topts[2]="0:10:00" ; popts[2]="16/4/" ; ropts[2]="/2"
@@ -310,19 +300,22 @@ if [[ "$machine" = "Hera" ]]; then
export APRUN="srun"
elif [[ "$machine" = "Orion" ]]; then
export OMP_STACKSIZE=2048M
- export APRUN="srun -n \$ntasks"
+ export APRUN="srun -n \$ntasks --mem=0 --cpus-per-task=\$threads"
+elif [[ "$machine" = "Hercules" ]]; then
+ export OMP_STACKSIZE=2048M
+ export APRUN="srun -n \$ntasks --mem=0 --cpus-per-task=\$threads"
elif [[ "$machine" = "Jet" ]]; then
export OMP_STACKSIZE=1024M
export MPI_BUFS_PER_PROC=256
export MPI_BUFS_PER_HOST=256
export MPI_GROUP_MAX=256
- export APRUN="srun"
-elif [[ "$machine" = "Cheyenne" ]]; then
+ export APRUN="srun -n \$ntasks --cpus-per-task=\$threads"
+elif [[ "$machine" = "Gaea" ]]; then
export OMP_STACKSIZE=1024M
export MPI_BUFS_PER_PROC=256
export MPI_BUFS_PER_HOST=256
export MPI_GROUP_MAX=256
- export APRUN="mpirun -v -np \$NCPUS"
+ export APRUN="srun --export=ALL -n \$ntasks"
elif [[ "$machine" = "wcoss2" ]]; then
export OMP_PLACES=cores
export OMP_STACKSIZE=2G
diff --git a/regression/regression_test.sh b/regression/regression_test.sh
index deb34ff244..263761052a 100755
--- a/regression/regression_test.sh
+++ b/regression/regression_test.sh
@@ -33,7 +33,6 @@ cd $tmpdir
# Other required constants for regression testing
maxtime=1200
-maxmem=${maxmem:-3400000} # set in regression_param
# Copy stdout and fort.220 files
# from $savdir to $tmpdir
@@ -182,24 +181,6 @@ fi
} >> $output
- # Next, maximum residence set size (both harware limitation and percent difference)
- # First, hardware limitation
-
- {
-
- if [[ $(awk '{ print $8 }' memory.$exp1.txt) -gt $maxmem ]]; then
- echo 'The memory for '$exp1' is '$(awk '{ print $8 }' memory.$exp1.txt)' KBs. This has exceeded maximum allowable hardware memory limit of '$maxmem' KBs,'
- echo 'resulting in Failure maxmem of the regression test.'
- echo
- failed_test=1
- else
- echo 'The memory for '$exp1' is '$(awk '{ print $8 }' memory.$exp1.txt)' KBs and is within the maximum allowable hardware memory limit of '$maxmem' KBs,'
- echo 'continuing with regression test.'
- echo
- fi
-
- } >> $output
-
# Next, maximum residence set size
{
@@ -348,7 +329,7 @@ fi
} >> $output
fi
- elif [[ `expr substr $exp1 1 4` = "rrfs" ]]; then
+ elif [[ `expr substr $exp1 1 4` = "rrfs" ]] || [[ `expr substr $exp1 1 4` = "hafs" ]]; then
{
fv3_failed_test=0
if cmp -s fv3_dynvars.${exp1} fv3_dynvars.${exp2}
@@ -520,7 +501,7 @@ elif [[ `expr substr $exp1 1 6` = "global" ]]; then
fi
-elif [[ `expr substr $exp1 1 4` = "rrfs" ]]; then
+elif [[ `expr substr $exp1 1 4` = "rrfs" ]] || [[ `expr substr $exp1 1 4` = "hafs" ]]; then
{
fv3_failed_test=0
if cmp -s fv3_dynvars.${exp1} fv3_dynvars.${exp3}
@@ -556,31 +537,25 @@ elif [[ `expr substr $exp1 1 4` = "rrfs" ]]; then
fi
- # Finally, scalability
-
- {
-
- timelogic=$( echo "$scale1thresh >= $scale2" | bc )
- if [[ "$timelogic" = 1 ]]; then
- echo 'The case has passed the scalability regression test.'
- echo 'The slope for the update ('$scale1thresh' seconds per node) is greater than or equal to that for the control ('$scale2' seconds per node).'
- else
- echo 'The case has Failed the scalability test.'
- echo 'The slope for the update ('$scale1thresh' seconds per node) is less than that for the control ('$scale2' seconds per node).'
- fi
-
- } >> $output
-
# Copy select results to $savdir
mkdir -p $vfydir
$ncp $output $vfydir/
+# Final check for any failed tests
+count=$(grep -i "fail" $output |wc -l)
+if [ $count -gt 0 ]; then
+ (( failed_test = $failed_test + $count ))
+fi
+
+# Remove job log files is no failures detected
cd $scripts
-rm -f ${exp1}.out
-rm -f ${exp2}.out
-rm -f ${exp3}.out
-rm -f ${exp2_scale}.out
+if [ $count -eq 0 ]; then
+ rm -f ${exp1}.out
+ rm -f ${exp2}.out
+ rm -f ${exp3}.out
+ rm -f ${exp2_scale}.out
+fi
if [[ "$clean" = ".true." ]]; then
rm -rf $savdir
diff --git a/regression/regression_test_enkf.sh b/regression/regression_test_enkf.sh
index 213ee726da..ac839631c2 100755
--- a/regression/regression_test_enkf.sh
+++ b/regression/regression_test_enkf.sh
@@ -31,22 +31,34 @@ cd $tmpdir
# Other required constants for regression testing
maxtime=1200
-maxmem=${maxmem:-3400000} # set in regression_param
-maxmem=$((${memnode:-64}*1024*1024))
-# Copy stdout and sanl files
+# Copy stdout and incr files
# from $savdir to $tmpdir
list="$exp1 $exp2 $exp3"
-for exp in $list; do
- $ncp $savdir/$exp/stdout ./stdout.$exp
- nmem=10
- imem=1
- while [[ $imem -le $nmem ]]; do
- member="_mem"`printf %03i $imem`
- $ncp $savdir/$exp/sanl_${global_adate}_fhr06$member $tmpdir/sanl$member.$exp
- (( imem = $imem + 1 ))
+if [[ $(expr substr $exp1 1 4) = "rrfs" ]]; then
+ for exp in $list; do
+ $ncp $savdir/$exp/stdout ./stdout.$exp
+ nmem=5
+ imem=1
+ while [[ $imem -le $nmem ]]; do
+ member="_mem"`printf %03i $imem`
+ $ncp $savdir/$exp/fv3sar_tile1_mem${member}_dynvars $tmpdir/dynvars$member.$exp
+ $ncp $savdir/$exp/fv3sar_tile1_mem${member}_tracer $tmpdir/tracer$member.$exp
+ (( imem = $imem + 1 ))
+ done
done
-done
+else
+ for exp in $list; do
+ $ncp $savdir/$exp/stdout ./stdout.$exp
+ nmem=10
+ imem=1
+ while [[ $imem -le $nmem ]]; do
+ member="_mem"`printf %03i $imem`
+ $ncp $savdir/$exp/incr_${global_adate}_fhr06$member $tmpdir/incr$member.$exp
+ (( imem = $imem + 1 ))
+ done
+ done
+fi
# Grep out ensemble mean increment information, run time, and maximum resident memory from stdout file
list="$exp1 $exp2 $exp3"
@@ -177,20 +189,6 @@ fi
# Next, maximum residence set size (both harware limitation and percent difference)
# First, hardware limitation
- {
-
- if [[ $(awk '{ print $8 }' memory.$exp1.txt) -gt $maxmem ]]; then
- echo 'The memory for '$exp1' is '$(awk '{ print $8 }' memory.$exp1.txt)' KBs. This has exceeded maximum allowable hardware memory limit of '$maxmem' KBs,'
- echo 'resulting in Failure maxmem of the regression test.'
- echo
- failed_test=1
- else
- echo 'The memory for '$exp1' is '$(awk '{ print $8 }' memory.$exp1.txt)' KBs and is within the maximum allowable hardware memory limit of '$maxmem' KBs,'
- echo 'continuing with regression test.'
- echo
- fi
-
- } >> $output
# Next, maximum residence set size
@@ -239,16 +237,36 @@ fi
# Next, check reproducibility of results between exp1 and exp2
-if [[ `expr substr $exp1 1 4` = "rtma" ]]; then
+if [[ $(expr substr $exp1 1 4) = "rrfs" ]]; then
{
-if cmp -s siganl.${exp1} siganl.${exp2}
-then
- echo 'The results between the two runs ('${exp1}' and '${exp2}') are reproducible'
- echo 'since the corresponding results are identical.'
- echo
-fi
+nmem=5
+imem=1
+while [[ $imem -le $nmem ]]; do
+ member="_mem"`printf %03i $imem`
+ ncdump dynvars$member.${exp1} > dynvars$member.${exp1}.out
+ ncdump dynvars$member.${exp2} > dynvars$member.${exp2}.out
+ if [ ! diff dynvars$member.${exp1}.out dynvars$member.${exp2}.out ]; then
+ echo 'dynvars'$member'.'${exp1}' dynvars'$member'.'${exp2}' are NOT identical'
+ failed_test=1
+ else
+ rm -f dynvars$member.${exp1}.out dynvars$member.${exp2}.out
+ echo 'dynvars'$member'.'${exp1}' dynvars'$member'.'${exp2}' are identical'
+ fi
+ ncdump tracer$member.${exp1} > tracers$member.${exp1}.out
+ ncdump tracer$member.${exp2} > tracers$member.${exp2}.out
+ if [ ! diff tracers$member.${exp1}.out tracers$member.${exp2}.out ]; then
+ echo 'tracer'$member'.'${exp1}' tracer'$member'.'${exp2}' are NOT identical'
+ failed_test=1
+ else
+ rm -f tracers$member.${exp1}.out tracers$member.${exp2}.out
+ echo 'tracer'$member'.'${exp1}' tracer'$member'.'${exp2}' are identical'
+ q
+ fi
+ (( imem = $imem + 1 ))
+done
+echo
} >> $output
@@ -282,10 +300,13 @@ nmem=10
imem=1
while [[ $imem -le $nmem ]]; do
member="_mem"`printf %03i $imem`
- if ! cmp -s sanl$member.${exp1} sanl$member.${exp2}
-then
- echo 'sanl'$member'.'${exp1}' sanl'$member'.'${exp2}' are NOT identical'
-fi
+ ncdump incr$member.${exp1} > incr$member.${exp1}.out
+ ncdump incr$member.${exp2} > incr$member.${exp2}.out
+ if [ ! diff incr$member.${exp1}.out incr$member.${exp2}.out ]; then
+ echo 'incr'$member'.'${exp1}' incr'$member'.'${exp2}' are NOT identical'
+ else
+ rm -f incr$member.${exp1}.out incr$member.${exp2}.out
+ fi
(( imem = $imem + 1 ))
done
echo
@@ -334,16 +355,35 @@ else
# Next, check reproducibility of results between exp1 and exp3
- if [[ `expr substr $exp1 1 4` = "rtma" ]]; then
+ if [[ $(expr substr $exp1 1 4) = "rrfs" ]]; then
{
- if cmp -s wrf_inout.${exp1} wrf_inout.${exp3}
- then
- echo 'The results between the two runs ('${exp1}' and '${exp3}') are reproducible'
- echo 'since the corresponding results are identical.'
- echo
- fi
+ nmem=5
+ imem=1
+ while [[ $imem -le $nmem ]]; do
+ member="_mem"`printf %03i $imem`
+ ncdump dynvars$member.${exp1} > dynvars$member.${exp1}.out
+ ncdump dynvars$member.${exp3} > dynvars$member.${exp3}.out
+ if [ ! diff dynvars$member.${exp1}.out dynvars$member.${exp3}.out ]; then
+ echo 'dynvars'$member'.'${exp1}' dynvars'$member'.'${exp3}' are NOT identical'
+ failed_test=1
+ else
+ rm -f dynvars$member.${exp1}.out dynvars$member.${exp3}.out
+ echo 'dynvars'$member'.'${exp1}' dynvars'$member'.'${exp3}' are identical'
+ fi
+ ncdump tracer$member.${exp1} > tracers$member.${exp1}.out
+ ncdump tracer$member.${exp3} > tracers$member.${exp3}.out
+ if [ ! diff tracers$member.${exp1}.out tracers$member.${exp3}.out ]; then
+ echo 'tracer'$member'.'${exp1}' tracer'$member'.'${exp3}' are NOT identical'
+ failed_test=1
+ else
+ rm -f tracers$member.${exp1}.out tracers$member.${exp3}.out
+ echo 'tracer'$member'.'${exp1}' tracer'$member'.'${exp3}' are identical'
+ fi
+ (( imem = $imem + 1 ))
+ done
+ echo
} >> $output
@@ -379,11 +419,14 @@ else
imem=1
while [[ $imem -le $nmem ]]; do
member="_mem"`printf %03i $imem`
- if ! cmp -s sanl$member.${exp1} sanl$member.${exp3}
- then
- echo 'sanl'$member'.'${exp1}' sanl'$member'.'${exp3}' are NOT identical'
+ ncdump incr$member.${exp1} > incr$member.${exp1}.out
+ ncdump incr$member.${exp3} > incr$member.${exp3}.out
+ if [ ! diff incr$member.${exp1}.out incr$member.${exp3}.out ]; then
+ echo 'incr'$member'.'${exp1}' incr'$member'.'${exp3}' are NOT identical'
+ else
+ rm -f incr$member.${exp1}.out incr$member.${exp3}.out
fi
- (( imem = $imem + 1 ))
+ (( imem = $imem + 1 ))
done
echo
} >> $output
@@ -391,31 +434,25 @@ else
fi
fi
- # Finally, scalability
-
- {
-
- timelogic=$( echo "$scale1thresh >= $scale2" | bc )
- if [[ "$timelogic" = 1 ]]; then
- echo 'The case has passed the scalability regression test.'
- echo 'The slope for the update ('$scale1thresh' seconds per node) is greater than or equal to that for the control ('$scale2' seconds per node).'
- else
- echo 'The case has Failed the scalability test.'
- echo 'The slope for the update ('$scale1thresh' seconds per node) is less than that for the control ('$scale2' seconds per node).'
- fi
-
- } >> $output
-
# Copy select results to $savdir
mkdir -p $vfydir
$ncp $output $vfydir/
+# Final check for any failed tests
+count=$(grep -i "fail" $output |wc -l)
+if [ $count -gt 0 ]; then
+ (( failed_test = $failed_test + $count ))
+fi
+
+# Remove job log files is no failures detected
cd $scripts
-rm -f ${exp1}.out
-rm -f ${exp2}.out
-rm -f ${exp3}.out
-rm -f ${exp2_scale}.out
+if [ $count -eq 0 ]; then
+ rm -f ${exp1}.out
+ rm -f ${exp2}.out
+ rm -f ${exp3}.out
+ rm -f ${exp2_scale}.out
+fi
if [[ "$clean" = ".true." ]]; then
rm -rf $savdir
diff --git a/regression/regression_var.sh b/regression/regression_var.sh
index 250317f405..4a2bc85874 100755
--- a/regression/regression_var.sh
+++ b/regression/regression_var.sh
@@ -14,6 +14,7 @@ if [ "$#" = 7 ] ; then
export enkfexec_contrl=$7
export fixgsi="$gsisrc/fix"
export scripts="$gsisrc/regression"
+ export modulefiles="$gsisrc/modulefiles"
export ush="$gsisrc/ush"
export cmaketest="true"
export clean="false"
@@ -29,40 +30,38 @@ else
fi
# Determine the machine
-if [[ -d /glade ]]; then # Cheyenne
- export machine="Cheyenne"
-elif [[ -d /scratch1 ]]; then # Hera
+if [[ -d /scratch1 ]]; then # Hera
export machine="Hera"
-elif [[ -d /jetmon ]]; then # Jet
+elif [[ -d /mnt/lfs4 || -d /jetmon || -d /mnt/lfs5 ]]; then # Jet
export machine="Jet"
elif [[ -d /discover ]]; then # NCCS Discover
export machine="Discover"
-elif [[ -d /sw/gaea ]]; then # Gaea
+elif [[ -d /ncrc ]]; then # Gaea
export machine="Gaea"
elif [[ -d /data/prod ]]; then # S4
export machine="S4"
-elif [[ -d /work ]]; then # Orion
- export machine="Orion"
+elif [[ -d /work ]]; then # Orion or Hercules
+ mount=$(findmnt -n -o SOURCE /home)
+ if [[ ${mount} =~ "hercules" ]]; then
+ export machine="Hercules"
+ else
+ export machine="Orion"
+ fi
elif [[ -d /lfs/h2 ]]; then # wcoss2
export machine="wcoss2"
fi
echo "Running Regression Tests on '$machine'";
case $machine in
- Cheyenne)
- export queue="economy"
- export noscrub="/glade/scratch/$LOGNAME"
- export group="global"
- if [[ "$cmaketest" = "false" ]]; then
- export basedir="/glade/scratch/$LOGNAME/gsi"
- fi
- export ptmp="/glade/scratch/$LOGNAME/$ptmpName"
-
- export fixcrtm="/glade/p/ral/jntp/tools/crtm/2.2.3/fix_update"
- export casesdir="/glade/p/ral/jntp/tools/CASES"
+ Gaea)
+ export queue="normal"
+ export group="ufs-ard"
+ export noscrub="/gpfs/f5/${group}/scratch/${USER}/$LOGNAME/gsi_tmp/noscrub"
+ export ptmp="/gpfs/f5/${group}/scratch/${USER}/$LOGNAME/gsi_tmp/ptmp"
+ export casesdir="/gpfs/f5/ufs-ard/world-shared/GSI_data/CASES/regtest"
export check_resource="no"
- export accnt="p48503002"
+ export accnt="ufs-ard"
;;
wcoss2)
export local_or_default="${local_or_default:-/lfs/h2/emc/da/noscrub/$LOGNAME}"
@@ -84,22 +83,28 @@ case $machine in
export check_resource="no"
export accnt="${accnt:-GFS-DEV}"
;;
- Orion)
+ Orion | Hercules)
export local_or_default="${local_or_default:-/work/noaa/da/$LOGNAME}"
if [ -d $local_or_default ]; then
- export noscrub="$local_or_default/noscrub"
+ export noscrub="$local_or_default/noscrub"
elif [ -d /work/noaa/global/$LOGNAME ]; then
- export noscrub="/work/noaa/global/$LOGNAME/noscrub"
+ export noscrub="/work/noaa/global/$LOGNAME/noscrub"
fi
export queue="${queue:-batch}"
+
+ if [[ "${machine}" == "Orion" ]]; then
+ export partition="${partition:-orion}"
+ else
+ export partition="${partition:-hercules}"
+ fi
+
export group="${group:-global}"
if [[ "$cmaketest" = "false" ]]; then
- export basedir="/work/noaa/da/$LOGNAME/gsi"
+ export basedir="/work/noaa/da/$LOGNAME/gsi"
fi
export ptmp="${ptmp:-/work/noaa/stmp/$LOGNAME/$ptmpName}"
- export fixcrtm=${CRTM_FIX:-/apps/contrib/NCEPLIBS/orion/fix/crtm_v2.3.0}
export casesdir="/work/noaa/da/rtreadon/CASES/regtest"
export check_resource="no"
@@ -124,7 +129,6 @@ case $machine in
export ptmp="${ptmp:-/scratch1/NCEPDEV/stmp2/$LOGNAME/$ptmpName}"
-## export fixcrtm="${CRTM_FIX:-/scratch1/NCEPDEV/da/Michael.Lueken/CRTM_REL-2.2.3/crtm_v2.2.3/fix_update}"
export casesdir="/scratch1/NCEPDEV/da/Russ.Treadon/CASES/regtest"
export check_resource="no"
@@ -136,21 +140,18 @@ case $machine in
;;
Jet)
- export noscrub=/lfs1/NESDIS/nesdis-rdo2/$LOGNAME/noscrub
- export ptmp=/lfs1/NESDIS/nesdis-rdo2/$LOGNAME/ptmp
- export fixcrtm="/lfs1/NESDIS/nesdis-rdo2/David.Huber/save/CRTM_REL-2.2.3/crtm_v2.2.3/fix_update"
- export casesdir="/lfs1/NESDIS/nesdis-rdo2/David.Huber/save/CASES"
+ export noscrub=/lfs5/NESDIS/nesdis-rdo2/$LOGNAME/noscrub
+ export ptmp=/lfs5/NESDIS/nesdis-rdo2/$LOGNAME/ptmp
+ export casesdir="/lfs5/NESDIS/nesdis-rdo2/David.Huber/save/CASES/regtest"
export check_resource="no"
export accnt="nesdis-rdo2"
export group="global"
export queue="batch"
if [[ "$cmaketest" = "false" ]]; then
- export basedir="/lfs1/NESDIS/nesdis-rdo2/$LOGNAME/gsi"
+ export basedir="/lfs5/NESDIS/nesdis-rdo2/$LOGNAME/save/git/gsi"
fi
- export ptmp="/lfs1/NESDIS/nesdis-rdo2/$LOGNAME/ptmp/$ptmpName"
-
# On Jet, there are no scrubbers to remove old contents from stmp* directories.
# After completion of regression tests, will remove the regression test subdirecories
export clean=".true."
@@ -163,7 +164,6 @@ case $machine in
export ptmp=$basedir
export ptmp=$basedir
export noscrub=$basedir
- export fixcrtm="/discover/nobackup/projects/gmao/share/gmao_ops/fvInput_4dvar/gsi/etc/fix_ncep20170329/REL-2.2.3-r60152_local-rev_1/CRTM_Coeffs/$endianness"
export casesdir="/discover/nobackup/projects/gmao/obsdev/wrmccart/NCEP_regression/CASES"
export check_resource="no"
export accnt="g0613"
@@ -176,18 +176,6 @@ case $machine in
;;
esac
-if [[ "$cmaketest" = "false" ]]; then
- export builddir=$noscrub/build
- export gsisrc="$basedir/$updat/src"
- export gsiexec_updat="$gsisrc/global_gsi.x"
- export gsiexec_contrl="$basedir/$contrl/src/global_gsi.x"
- export enkfexec_updat="$gsisrc/enkf/global_enkf.x"
- export enkfexec_contrl="$basedir/$contrl/src/enkf/global_enkf.x"
- export fixgsi="$basedir/$updat/fix"
- export scripts="$basedir/$updat/regression"
- export ush="$basedir/$updat/ush"
-fi
-
# We are dealing with *which* endian files
export endianness="Big_Endian"
@@ -201,23 +189,25 @@ export savdir="$ptmp"
export JCAP="62"
# Case Study analysis dates
-export global_adate="2022110900"
+export global_adate="2024022300"
export rtma_adate="2020022420"
-export hwrf_nmm_adate="2012102812"
-export fv3_netcdf_adate="2017030100"
-export rrfs_3denvar_glbens_adate="2021072518"
+export rrfs_enkf_adate="2023061012"
+export rrfs_3denvar_rdasens_adate="2023061012"
+export hafs_envar_adate="2020082512"
# Paths for canned case data.
export global_data="$casesdir/gfs/prod"
export rtma_obs="$casesdir/regional/rtma_binary/$rtma_adate"
export rtma_ges="$casesdir/regional/rtma_binary/$rtma_adate"
-export hwrf_nmm_obs="$casesdir/regional/hwrf_nmm/$hwrf_nmm_adate"
-export hwrf_nmm_ges="$casesdir/regional/hwrf_nmm/$hwrf_nmm_adate"
-export fv3_netcdf_obs="$casesdir/regional/fv3_netcdf/$fv3_netcdf_adate"
-export fv3_netcdf_ges="$casesdir/regional/fv3_netcdf/$fv3_netcdf_adate"
-export rrfs_3denvar_glbens_obs="$casesdir/regional/rrfs/$rrfs_3denvar_glbens_adate/obs"
-export rrfs_3denvar_glbens_ges="$casesdir/regional/rrfs/$rrfs_3denvar_glbens_adate/ges"
-export rrfs_3denvar_glbens_ens="$casesdir/regional/rrfs/$rrfs_3denvar_glbens_adate/ens"
+export rrfs_enkf_diag="$casesdir/regional/rrfs/$rrfs_enkf_adate/diag"
+export rrfs_enkf_ges="$casesdir/regional/rrfs/$rrfs_enkf_adate/ens"
+export rrfs_3denvar_rdasens_obs="$casesdir/regional/rrfs/$rrfs_3denvar_rdasens_adate/obs"
+export rrfs_3denvar_rdasens_ges="$casesdir/regional/rrfs/$rrfs_3denvar_rdasens_adate/ges"
+export rrfs_3denvar_rdasens_ens="$casesdir/regional/rrfs/$rrfs_3denvar_rdasens_adate/ens"
+export hafs_envar_obs="$casesdir/regional/hafs_RTdata/$hafs_envar_adate/obs"
+export hafs_envar_ges="$casesdir/regional/hafs_RTdata/$hafs_envar_adate/ges"
+export hafs_envar_ens="$casesdir/regional/hafs_RTdata/$hafs_envar_adate/ens"
+
# Define type of GPSRO data to be assimilated (refractivity or bending angle)
export gps_dtype="gps_bnd"
@@ -228,7 +218,7 @@ export regression_vfydir="$noscrub/regression"
# Define debug variable - If you want to run the debug tests, set this variable to .true. Default is .false.
export debug=".false."
-# Define parameters for global_3dvar, global_4dvar, global_4denvar
+# Define parameters for global_4denvar
export minimization="lanczos" # If "lanczos", use sqrtb lanczos minimization algorithm. Otherwise use "pcgsoi".
export nhr_obsbin="6" # Time window for observation binning. Use "6" for 3d4dvar test. Otherwise use "1"
diff --git a/regression/rrfs_3denvar_glbens.sh b/regression/rrfs_3denvar_rdasens.sh
similarity index 55%
rename from regression/rrfs_3denvar_glbens.sh
rename to regression/rrfs_3denvar_rdasens.sh
index af5da51172..b00047ec65 100755
--- a/regression/rrfs_3denvar_glbens.sh
+++ b/regression/rrfs_3denvar_rdasens.sh
@@ -21,7 +21,7 @@ exp=$jobname
#
#-----------------------------------------------------------------------
#
-adate=${rrfs_3denvar_glbens_adate}
+adate=${rrfs_3denvar_rdasens_adate}
YYYYMMDDHH=$(date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2}")
JJJ=$(date +%j -d "${adate:0:8} ${adate:8:2}")
@@ -31,9 +31,6 @@ DD=${YYYYMMDDHH:6:2}
HH=${YYYYMMDDHH:8:2}
YYYYMMDD=${YYYYMMDDHH:0:8}
#
-#MESO_USELIST_FN=$(date +%Y-%m-%d -d "${START_DATE} -1 day")_meso_uselist.txt
-#AIR_REJECT_FN=$(date +%Y%m%d -d "${START_DATE} -1 day")_rejects.txt
-
#
#-----------------------------------------------------------------------
#
@@ -42,17 +39,16 @@ YYYYMMDD=${YYYYMMDDHH:0:8}
#
#-----------------------------------------------------------------------
# Set runtime and save directories
-tmpdir=$tmpdir/tmpreg_rrfs_3denvar_glbens/${exp}
-savdir=$savdir/outreg_rrfs_3denvar_glbens/${exp}
+tmpdir=$tmpdir/tmpreg_rrfs_3denvar_rdasens/${exp}
+savdir=$savdir/outreg_rrfs_3denvar_rdasens/${exp}
# Set up $tmpdir
rm -rf $tmpdir
mkdir -p $tmpdir
-chgrp rstprod $tmpdir
chmod 750 $tmpdir
cd $tmpdir
-bkpath=${rrfs_3denvar_glbens_ges}
+bkpath=${rrfs_3denvar_rdasens_ges}
# decide background type
if [ -r "${bkpath}/fv3_coupler.res" ]; then
BKTYPE=0 # warm start
@@ -68,19 +64,59 @@ fixcrtm=${fixcrtm:-$CRTM_FIX}
#
#---------------------------------------------------------------------
#
-echo "regional_ensemble_option is ",${regional_ensemble_option:-1}
-
+regional_ensemble_option=${regional_ensemble_option:-5}
+NUM_ENS_MEMBERS=5
+echo "regional_ensemble_option is ",${regional_ensemble_option}
+echo "regional_ensemble number is ",${NUM_ENS_MEMBERS}
echo "$VERBOSE" "fixgsi is $fixgsi"
-echo "$VERBOSE" "fixgriddir is $fixgriddir"
echo "$VERBOSE" "default bkpath is $bkpath"
echo "$VERBOSE" "background type is is $BKTYPE"
ifhyb=.false.
-if [[ ${regional_ensemble_option:-1} -eq 1 ]]; then #using GDAS
+#
+# Check if we have enough FV3-LAM ensembles when regional_ensemble_option=5
+#
+if [[ ${regional_ensemble_option} -eq 5 ]]; then
+
+ imem=1
+ ifound=0
+ while [[ $imem -le ${NUM_ENS_MEMBERS} ]];do
+ memcharv0=$( printf "%03d" $imem )
+ memchar=mem$( printf "%04d" $imem )
+
+ restart_prefix="${YYYYMMDD}.${HH}0000."
+ slash_ensmem_subdir=$memchar
+ bkpathmem=${rrfs_3denvar_rdasens_ens}/${slash_ensmem_subdir}/fcst_fv3lam/RESTART
+
+ dynvarfile=${bkpathmem}/${restart_prefix}fv_core.res.tile1.nc
+ tracerfile=${bkpathmem}/${restart_prefix}fv_tracer.res.tile1.nc
+ phyvarfile=${bkpathmem}/${restart_prefix}phy_data.nc
+ if [ -r "${dynvarfile}" ] && [ -r "${tracerfile}" ] && [ -r "${phyvarfile}" ] ; then
+ ln -snf ${bkpathmem}/${restart_prefix}fv_core.res.tile1.nc fv3SAR01_ens_mem${memcharv0}-fv3_dynvars
+ ln -snf ${bkpathmem}/${restart_prefix}fv_tracer.res.tile1.nc fv3SAR01_ens_mem${memcharv0}-fv3_tracer
+ ln -snf ${bkpathmem}/${restart_prefix}phy_data.nc fv3SAR01_ens_mem${memcharv0}-fv3_phyvars
+ (( ifound += 1 ))
+ else
+ print_info_msg "WARNING: Cannot find ensemble files: ${dynvarfile} ${tracerfile} ${phyvarfile} "
+ fi
+ (( imem += 1 ))
+ done
+
+ ifhyb=.true.
+ nummem=${NUM_ENS_MEMBERS}
+ if [[ $ifound -ne ${NUM_ENS_MEMBERS} ]] || [[ ${BKTYPE} -eq 1 ]]; then
+ print_info_msg "Not enough FV3_LAM ensembles, will fall to GDAS"
+ regional_ensemble_option=1
+ l_both_fv3sar_gfs_ens=.false.
+ ifhyb=.false.
+ fi
+fi
+#
+if [[ ${regional_ensemble_option} -eq 1 ]]; then #using GDAS
#-----------------------------------------------------------------------
# Make a list of the latest GFS EnKF ensemble
#-----------------------------------------------------------------------
- ls ${rrfs_3denvar_glbens_ens}/*gdas.t??z.atmf009.mem0??.nc >> filelist03
+ ls ${rrfs_3denvar_rdasens_ens}/*gdas.t??z.atmf009.mem0??.nc >> filelist03
nummem=$(more filelist03 | wc -l)
nummem=$((nummem - 3 ))
@@ -109,12 +145,13 @@ ln -snf ${bkpath}/fv3_akbk fv3_akbk
ln -snf ${bkpath}/fv3_grid_spec fv3_grid_spec
if [ ${BKTYPE} -eq 1 ]; then # cold start uses background from INPUT
- ln -snf ${bkpath}/phis.nc phis.nc
- ncks -A -v phis phis.nc ${bkpath}/gfs_data.tile7.halo0.nc
- ln_vrfy -snf ${bkpath}/sfc_data.tile7.halo0.nc fv3_sfcdata
- ln_vrfy -snf ${bkpath}/gfs_data.tile7.halo0.nc fv3_dynvars
- ln_vrfy -s fv3_dynvars fv3_tracer
+ cp ${bkpath}/sfc_data.tile7.halo0.nc fv3_sfcdata
+ cp ${bkpath}/gfs_data.tile7.halo0.nc fv3_dynvars
+ ln_vrfy -s fv3_dynvars fv3_tracer
+
+ ln -snf ${bkpath}/phis.nc phis.nc
+ ncks -A -v phis phis.nc fv3_dynvars
fv3lam_bg_type=1
else # cycle uses background from restart
@@ -133,7 +170,6 @@ sed -i "s/mm/${MM}/" coupler.res
sed -i "s/dd/${DD}/" coupler.res
sed -i "s/hh/${HH}/" coupler.res
-
#
#-----------------------------------------------------------------------
#
@@ -143,7 +179,7 @@ sed -i "s/hh/${HH}/" coupler.res
#-----------------------------------------------------------------------
obs_source=rap
obsfileprefix=${YYYYMMDDHH}.${obs_source}
- obspath_tmp=${rrfs_3denvar_glbens_obs}
+ obspath_tmp=${rrfs_3denvar_rdasens_obs}
obs_files_source[0]=${obspath_tmp}/${obsfileprefix}.t${HH}${SUBH}z.prepbufr.tm00
obs_files_target[0]=prepbufr
@@ -156,6 +192,73 @@ sed -i "s/hh/${HH}/" coupler.res
obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}${SUBH}z.nexrad.tm00.bufr_d
obs_files_target[${obs_number}]=l2rwbufr
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${YYYYMMDDHH}.Gridded_ref.nc
+ obs_files_target[${obs_number}]=dbzobs.nc
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${YYYYMMDDHH}.fedobs.nc
+ obs_files_target[${obs_number}]=fedobs.nc
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.1bamua.tm00.bufr_d
+ obs_files_target[${obs_number}]=amsuabufr
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.esamua.tm00.bufr_d
+ obs_files_target[${obs_number}]=amsuabufrears
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.1bmhs.tm00.bufr_d
+ obs_files_target[${obs_number}]=mhsbufr
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.esmhs.tm00.bufr_d
+ obs_files_target[${obs_number}]=mhsbufrears
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.atms.tm00.bufr_d
+ obs_files_target[${obs_number}]=atmsbufr
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.esatms.tm00.bufr_d
+ obs_files_target[${obs_number}]=atmsbufrears
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.atmsdb.tm00.bufr_d
+ obs_files_target[${obs_number}]=atmsbufr_db
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.crisf4.tm00.bufr_d
+ obs_files_target[${obs_number}]=crisfsbufr
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.crsfdb.tm00.bufr_d
+ obs_files_target[${obs_number}]=crisfsbufr_db
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.mtiasi.tm00.bufr_d
+ obs_files_target[${obs_number}]=iasibufr
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.esiasi.tm00.bufr_d
+ obs_files_target[${obs_number}]=iasibufrears
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.iasidb.tm00.bufr_d
+ obs_files_target[${obs_number}]=iasibufr_db
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.gsrcsr.tm00.bufr_d
+ obs_files_target[${obs_number}]=abibufr
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.ssmisu.tm00.bufr_d
+ obs_files_target[${obs_number}]=ssmisbufr
+
+ obs_number=${#obs_files_source[@]}
+ obs_files_source[${obs_number}]=${obspath_tmp}/${obsfileprefix}.t${HH}z.sevcsr.tm00.bufr_d
+ obs_files_target[${obs_number}]=sevcsr
obs_number=${#obs_files_source[@]}
for (( i=0; i<${obs_number}; i++ ));
@@ -176,7 +279,7 @@ done
#
#-----------------------------------------------------------------------
-ANAVINFO=${fixgsi}/anavinfo.rrfs
+ANAVINFO=${fixgsi}/anavinfo.rrfs_conv_dbz
CONVINFO=${fixgsi}/convinfo.rrfs
HYBENSINFO=${fixgsi}/hybens_info.rrfs
OBERROR=${fixgsi}/errtable.rrfs
@@ -198,9 +301,31 @@ cp $OBERROR errtable
cp $ATMS_BEAMWIDTH atms_beamwidth.txt
cp ${HYBENSINFO} hybens_info
-cp ${bkpath}/gsd_sfcobs_provider.txt gsd_sfcobs_provider.txt
-cp ${bkpath}/current_bad_aircraft current_bad_aircraft
-cp ${bpath}/gsd_sfcobs_uselist.txt gsd_sfcobs_uselist.txt
+cp ${obspath_tmp}/gsd_sfcobs_provider.txt gsd_sfcobs_provider.txt
+cp ${obspath_tmp}/current_bad_aircraft current_bad_aircraft
+cp ${obspath_tmp}/gsd_sfcobs_uselist.txt gsd_sfcobs_uselist.txt
+
+#-----------------------------------------------------------------------
+#
+# cycling radiance bias corretion files
+#
+#-----------------------------------------------------------------------
+
+cp $obspath_tmp/rrfs.prod.${YYYYMMDDHH}_satbias_pc ./satbias_pc
+cp $obspath_tmp/rrfs.prod.${YYYYMMDDHH}_satbias ./satbias_in
+cp $obspath_tmp/rrfs.prod.${YYYYMMDDHH}_radstat ./radstat.rrfs
+
+if [ -r radstat.rrfs ]; then
+ listdiag=$(tar xvf radstat.rrfs | cut -d' ' -f2 | grep _ges)
+ for type in $listdiag; do
+ diag_file=$(echo $type | cut -d',' -f1)
+ fname=$(echo $diag_file | cut -d'.' -f1)
+ date=$(echo $diag_file | cut -d'.' -f2)
+ gunzip $diag_file
+ fnameanl=$(echo $fname|sed 's/_ges//g')
+ mv $fname.$date* $fnameanl
+ done
+fi
#-----------------------------------------------------------------------
#
@@ -261,9 +386,9 @@ HYBRID_ENSEMBLE='ensemble_path="",'
SINGLEOB="$SINGLEOB_update"
if [ "$debug" = ".false." ]; then
- . $scripts/regression_namelists.sh rrfs_3denvar_glbens
+ . $scripts/regression_namelists.sh rrfs_3denvar_rdasens
else
- . $scripts/regression_namelists_db.sh rrfs_3denvar_glbens
+ . $scripts/regression_namelists_db.sh rrfs_3denvar_rdasens
fi
cat << EOF > gsiparm.anl
@@ -279,10 +404,6 @@ elif [[ $exp == *"contrl"* ]]; then
$ncp $gsiexec_contrl ./gsi.x
fi
-#cp $fv3_netcdf_ges/nam.t06z.satbias_pc.tm04 ./satbias_pc
-#cp $fv3_netcdf_ges/nam.t06z.satbias.tm04 ./satbias_in
-#cp $fv3_netcdf_ges/nam.t06z.radstat.tm04 ./radstat.gdas
-
# Run GSI
cd $tmpdir
echo "run gsi now"
diff --git a/regression/rrfs_enkf_conv.sh b/regression/rrfs_enkf_conv.sh
new file mode 100755
index 0000000000..21f7aacee2
--- /dev/null
+++ b/regression/rrfs_enkf_conv.sh
@@ -0,0 +1,223 @@
+
+set -x
+
+# Set variables used in script
+# CLEAN up $tmpdir when finished (YES=remove, NO=leave alone)
+# ncp is cp replacement, currently keep as /bin/cp
+
+UNCOMPRESS=gunzip
+CLEAN=NO
+ncp=/bin/cp
+#
+# Set experiment name
+#
+exp=$jobname
+
+#-----------------------------------------------------------------------
+#
+# Extract from ADATE the starting year, month, day, and hour of the
+# forecast. These are needed below for various operations.
+#
+#-----------------------------------------------------------------------
+#
+
+adate=${rrfs_enkf_adate}
+YYYYMMDDHH=$(date +%Y%m%d%H -d "${adate:0:8} ${adate:8:2}")
+JJJ=$(date +%j -d "${adate:0:8} ${adate:8:2}")
+
+YYYY=${YYYYMMDDHH:0:4}
+MM=${YYYYMMDDHH:4:2}
+DD=${YYYYMMDDHH:6:2}
+HH=${YYYYMMDDHH:8:2}
+YYYYMMDD=${YYYYMMDDHH:0:8}
+
+#
+#-----------------------------------------------------------------------
+#
+# go to working directory and save directory.
+# define fix and background path
+#
+#-----------------------------------------------------------------------
+# Set runtime and save directories
+tmpdir=$tmpdir/tmpreg_rrfs_enkf_conv/${exp}
+savdir=$savdir/outreg_rrfs_enkf_conv/${exp}
+
+# Set up $tmpdir
+rm -rf $tmpdir
+mkdir -p $tmpdir
+chmod 750 $tmpdir
+cd $tmpdir
+
+fixcrtm=${fixcrtm:-$CRTM_FIX}
+
+cp ${rrfs_3denvar_rdasens_ges}/fv3_coupler.res coupler.res
+cp ${rrfs_3denvar_rdasens_ges}/fv3_akbk fv3sar_tile1_akbk.nc
+cp ${rrfs_3denvar_rdasens_ges}/fv3_grid_spec fv3sar_tile1_grid_spec.nc
+
+#
+#-----------------------------------------------------------------------
+#
+# Loop through the members, link the background and copy over
+# observer output (diag*ges*) files to the running directory
+#
+#-----------------------------------------------------------------------
+#
+ob_type="conv"
+DO_ENS_RADDA="false"
+nens=${nens:-5}
+netcdf_diag=".true."
+for imem in $(seq 1 $nens) ensmean; do
+
+ if [ "${imem}" = "ensmean" ]; then
+ memchar="ensmean"
+ memcharv0="ensmean"
+ restart_prefix=""
+ else
+ memchar="mem"$(printf %04i $imem)
+ memcharv0="mem"$(printf %03i $imem)
+ restart_prefix="${YYYYMMDD}.${HH}0000."
+ fi
+ slash_ensmem_subdir=$memchar
+ bkpath=${rrfs_enkf_ges}/${slash_ensmem_subdir}/fcst_fv3lam/RESTART
+ observer_nwges_dir="${rrfs_enkf_diag}/${slash_ensmem_subdir}/observer_gsi"
+
+ cp ${bkpath}/${restart_prefix}fv_core.res.tile1.nc fv3sar_tile1_${memcharv0}_dynvars
+ cp ${bkpath}/${restart_prefix}fv_tracer.res.tile1.nc fv3sar_tile1_${memcharv0}_tracer
+ cp ${bkpath}/${restart_prefix}sfc_data.nc fv3sar_tile1_${memcharv0}_sfcdata
+ cp ${bkpath}/${restart_prefix}phy_data.nc fv3sar_tile1_${memcharv0}_phyvar
+
+ #
+#-----------------------------------------------------------------------
+#
+# Copy observer outputs (diag*ges*) to the working directory
+#
+#-----------------------------------------------------------------------
+#
+ if [ "${netcdf_diag}" = ".true." ] ; then
+ # Note, listall_rad is copied from exrrfs_run_analysis.sh
+ listall_rad="hirs2_n14 msu_n14 sndr_g08 sndr_g11 sndr_g11 sndr_g12 sndr_g13 sndr_g08_prep sndr_g11_prep sndr_g12_prep sndr_g13_prep sndrd1_g11 sndrd2_g11 sndrd3_g11 sndrd4_g11 sndrd1_g15 sndrd2_g15 sndrd3_g15 sndrd4_g15 sndrd1_g13 sndrd2_g13 sndrd3_g13 sndrd4_g13 hirs3_n15 hirs3_n16 hirs3_n17 amsua_n15 amsua_n16 amsua_n17 amsua_n18 amsua_n19 amsua_metop-a amsua_metop-b amsua_metop-c amsub_n15 amsub_n16 amsub_n17 hsb_aqua airs_aqua amsua_aqua imgr_g08 imgr_g11 imgr_g12 pcp_ssmi_dmsp pcp_tmi_trmm conv sbuv2_n16 sbuv2_n17 sbuv2_n18 omi_aura ssmi_f13 ssmi_f14 ssmi_f15 hirs4_n18 hirs4_metop-a mhs_n18 mhs_n19 mhs_metop-a mhs_metop-b mhs_metop-c amsre_low_aqua amsre_mid_aqua amsre_hig_aqua ssmis_las_f16 ssmis_uas_f16 ssmis_img_f16 ssmis_env_f16 iasi_metop-a iasi_metop-b iasi_metop-c seviri_m08 seviri_m09 seviri_m10 seviri_m11 cris_npp atms_npp ssmis_f17 cris-fsr_npp cris-fsr_n20 atms_n20 abi_g16"
+
+
+ if [ "${ob_type}" = "conv" ]; then
+ list_ob_type="conv_ps conv_q conv_t conv_uv conv_pw conv_rw conv_sst"
+
+ if [ "${DO_ENS_RADDA}" = "TRUE" ]; then
+ list_ob_type="$list_ob_type $listall_rad"
+ fi
+ fi
+
+ if [ "${ob_type}" = "radardbz" ]; then
+ if [ ${DO_GLM_FED_DA} == "TRUE" ]; then
+ list_ob_type="conv_dbz conv_fed"
+ else
+ list_ob_type="conv_dbz"
+ fi
+ fi
+ for sub_ob_type in ${list_ob_type} ; do
+ diagfile0=${observer_nwges_dir}/diag_${sub_ob_type}_ges.${YYYYMMDDHH}.nc4.gz
+ if [ -s $diagfile0 ]; then
+ diagfile=$(basename $diagfile0)
+ cp $diagfile0 $diagfile
+ gzip -d $diagfile && rm -f $diagfile
+ ncfile0=$(basename -s .gz $diagfile)
+ ncfile=$(basename -s .nc4 $ncfile0)
+ mv $ncfile0 ${ncfile}_${memcharv0}.nc4
+ fi
+ done
+ else
+ for diagfile0 in $(ls ${observer_nwges_dir}/diag*${ob_type}*ges* ) ; do
+ if [ -s $diagfile0 ]; then
+ diagfile=$(basename $diagfile0)
+ cp $diagfile0 diag_conv_ges.$memcharv0
+ fi
+ done
+ fi
+done
+
+#
+#-----------------------------------------------------------------------
+#
+# Set GSI fix files
+#
+#----------------------------------------------------------------------
+#
+found_ob_type=0
+
+CONVINFO=${fixgsi}/convinfo.rrfs
+
+if [ "${ob_type}" = "conv" ]; then
+ ANAVINFO=${fixgsi}/anavinfo.rrfs
+ found_ob_type=1
+fi
+if [ "${ob_type}" = "radardbz" ]; then
+ ANAVINFO=${fixgsi}/anavinfo.enkf.rrfs_dbz
+ CORRLENGTH="18"
+ LNSIGCUTOFF="0.5"
+ found_ob_type=1
+fi
+if [ ${found_ob_type} == 0 ]; then
+ err_exit "Unknown observation type: ${ob_type}"
+fi
+stdout_name=stdout.${ob_type}
+stderr_name=stderr.${ob_type}
+
+SATINFO=${fixgsi}/global_satinfo.txt
+OZINFO=${fixgsi}/global_ozinfo.txt
+
+cp ${ANAVINFO} anavinfo
+cp $SATINFO satinfo
+cp $CONVINFO convinfo
+cp $OZINFO ozinfo
+
+#
+#-----------------------------------------------------------------------
+#
+# Get nlons (NX_RES), nlats (NY_RES) and nlevs
+#
+#-----------------------------------------------------------------------
+#
+NX_RES=$(ncdump -h fv3sar_tile1_grid_spec.nc | grep "grid_xt =" | cut -f3 -d" " )
+NY_RES=$(ncdump -h fv3sar_tile1_grid_spec.nc | grep "grid_yt =" | cut -f3 -d" " )
+nlevs=$(ncdump -h fv3sar_tile1_mem001_tracer | grep "zaxis_1 =" | cut -f3 -d" " )
+#
+#----------------------------------------------------------------------
+#
+# Set namelist parameters for EnKF
+#
+#----------------------------------------------------------------------
+#
+EnKFTracerVars=${EnKFTracerVar:-"sphum,o3mr"}
+ldo_enscalc_option=${ldo_enscalc_option:-0}
+
+# Make gsi namelist
+
+. $scripts/regression_namelists.sh rrfs_enkf_conv
+
+#
+
+cat << EOF > enkf.nml
+
+$gsi_namelist
+
+EOF
+
+#
+#-----------------------------------------------------------------------
+#
+# Run the EnKF
+#
+#-----------------------------------------------------------------------
+#
+# Copy executable and fixed files to $tmpdir
+if [[ $exp == *"updat"* ]]; then
+ $ncp $enkfexec_updat ./enkf.x
+elif [[ $exp == *"contrl"* ]]; then
+ $ncp $enkfexec_contrl ./enkf.x
+fi
+
+# Run enkf
+cd $tmpdir
+echo "run rrfs enkf now"
+eval "$APRUN $tmpdir/enkf.x < enkf.nml > stdout 2>&1"
+rc=$?
+exit $rc
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a2eb249456..2f88b978c6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,6 +3,11 @@ if(BUILD_GSDCLOUD)
add_subdirectory(GSD)
endif()
+if(BUILD_MGBF)
+ message(STATUS "Building MGBF library")
+ add_subdirectory(mgbf)
+endif()
+
if(BUILD_GSI)
message(STATUS "Building GSI")
add_subdirectory(gsi)
diff --git a/src/enkf/controlvec.f90 b/src/enkf/controlvec.f90
index bb2421c89c..0961549634 100644
--- a/src/enkf/controlvec.f90
+++ b/src/enkf/controlvec.f90
@@ -51,7 +51,7 @@ module controlvec
use gridinfo, only: getgridinfo, gridinfo_cleanup, &
npts, vars3d_supported, vars2d_supported
use params, only: nlevs, nbackgrounds, fgfileprefixes, reducedgrid, &
- nanals, pseudo_rh, use_qsatensmean, nlons, nlats,&
+ nanals, pseudo_rh, nlons, nlats,&
nanals_per_iotask, ntasks_io, nanal1, nanal2, &
fgsfcfileprefixes, paranc, write_fv3_incr, write_ensmean
use kinds, only: r_kind, i_kind, r_double, r_single
@@ -64,7 +64,6 @@ module controlvec
public :: read_control, write_control, controlvec_cleanup, init_controlvec
real(r_single), public, allocatable, dimension(:,:,:,:) :: grdin
real(r_double), public, allocatable, dimension(:,:,:,:) :: qsat
-real(r_double), public, allocatable, dimension(:,:,:) :: qsatmean
integer(i_kind), public :: nc2d, nc3d, ncdim
character(len=max_varname_length), allocatable, dimension(:), public :: cvars3d
@@ -131,7 +130,7 @@ subroutine init_controlvec()
cvars3d(nc3d) = trim(adjustl(var))
clevels(nc3d) = ilev + clevels(nc3d-1)
else
- if (nproc .eq. 0) print *,'Error: only ', nlevs, ' and ', nlevs+1,' number of levels is supported in current version, got ',ilev
+ if (nproc .eq. 0) print *,'Error controlvec: only ', nlevs, ' and ', nlevs+1,' number of levels is supported in current version, got ',ilev
call stop2(503)
endif
enddo
@@ -160,7 +159,7 @@ subroutine init_controlvec()
do i = 1, nc2d
if (getindex(vars2d_supported, cvars2d(i))<0) then
if (nproc .eq. 0) then
- print *,'Error: 2D variable ', cvars2d(i), ' is not supported in current version.'
+ print *,'Error: control 2D variable ', cvars2d(i), ' is not supported in current version.'
print *,'Supported variables: ', vars2d_supported
endif
call stop2(502)
@@ -169,7 +168,7 @@ subroutine init_controlvec()
do i = 1, nc3d
if (getindex(vars3d_supported, cvars3d(i))<0) then
if (nproc .eq. 0) then
- print *,'Error: 3D variable ', cvars3d(i), ' is not supported in current version.'
+ print *,'Error: control 3D variable ', cvars3d(i), ' is not supported in current version.'
print *,'Supported variables: ', vars3d_supported
endif
call stop2(502)
@@ -192,7 +191,6 @@ subroutine read_control()
! read ensemble members on IO tasks
implicit none
real(r_double) :: t1,t2
-real(r_double), allocatable, dimension(:) :: qsat_tmp
integer(i_kind) :: nb,nlev,ne
integer(i_kind) :: q_ind
integer(i_kind) :: ierr
@@ -212,70 +210,39 @@ subroutine read_control()
! read in whole control vector on i/o procs - keep in memory
! (needed in write_ensemble)
allocate(grdin(npts,ncdim,nbackgrounds,nanals_per_iotask))
-allocate(qsat(npts,nlevs,nbackgrounds,nanals_per_iotask))
+! if only updating the sfc fields, qsat will not be calculated in readgriddata
+! only allocate if needed.
+q_ind = getindex(cvars3d, 'q')
+if (q_ind > 0) allocate(qsat(npts,nlevs,nbackgrounds,nanals_per_iotask))
if (paranc) then
if (nproc == 0) t1 = mpi_wtime()
call readgriddata_pnc(cvars3d,cvars2d,nc3d,nc2d,clevels,ncdim,nbackgrounds, &
fgfileprefixes,fgsfcfileprefixes,reducedgrid,grdin,qsat)
+ if (nproc == 0) then
+ t2 = mpi_wtime()
+ print *,'time in readgrid_pnc on root',t2-t1,'secs'
+ end if
end if
if (nproc <= ntasks_io-1) then
if (.not. paranc) then
if (nproc == 0) t1 = mpi_wtime()
call readgriddata(nanal1(nproc),nanal2(nproc),cvars3d,cvars2d,nc3d,nc2d,clevels,ncdim,nbackgrounds, &
fgfileprefixes,fgsfcfileprefixes,reducedgrid,grdin,qsat)
+ if (nproc == 0) then
+ t2 = mpi_wtime()
+ print *,'time in readgrid on root',t2-t1,'secs'
+ end if
end if
!print *,'min/max qsat',nanal,'=',minval(qsat),maxval(qsat)
- if (use_qsatensmean) then
- allocate(qsatmean(npts,nlevs,nbackgrounds))
- allocate(qsat_tmp(npts))
- ! compute ensemble mean qsat
- qsatmean = 0_r_double
- do ne=1,nanals_per_iotask
- do nb=1,nbackgrounds
- do nlev=1,nlevs
- call mpi_allreduce(qsat(:,nlev,nb,ne),qsat_tmp,npts,mpi_real8,mpi_sum,mpi_comm_io,ierr)
- qsatmean(:,nlev,nb) = qsatmean(:,nlev,nb) + qsat_tmp
- enddo
- enddo
- enddo
- deallocate(qsat_tmp)
- qsatmean = qsatmean/real(nanals)
- !print *,'min/max qsat ensmean',nanal,'=',minval(qsat),maxval(qsat)
- endif
- if (nproc == 0) then
- t2 = mpi_wtime()
- print *,'time in readgridata on root',t2-t1,'secs'
- end if
- !do ne=1,nanals_per_iotask
- ! nanal = ne + (nproc-1)*nanals_per_iotask
- ! print *,'min/max ps ens mem',nanal,'=',&
- ! minval(grdin(:,ncdim,nbackgrounds/2+1,ne)),maxval(grdin(:,ncdim,nbackgrounds/2+1,ne))
- ! print *,'min/max qsat',nanal,'=',&
- ! minval(qsat(:,:,nbackgrounds/2+1,ne)),maxval(qsat(:,:,nbackgrounds/2+1,ne))
- !enddo
- !if (use_qsatensmean) then
- ! print *,'min/max qsatmean proc',nproc,'=',&
- ! minval(qsatmean(:,:,nbackgrounds/2+1)),maxval(qsatmean(:,:,nbackgrounds/2+1))
- !endif
q_ind = getindex(cvars3d, 'q')
if (pseudo_rh .and. q_ind > 0) then
- if (use_qsatensmean) then
- do ne=1,nanals_per_iotask
- do nb=1,nbackgrounds
- ! create normalized humidity analysis variable.
- grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne) = &
- grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne)/qsatmean(:,:,nb)
- enddo
- enddo
- else
- do ne=1,nanals_per_iotask
- do nb=1,nbackgrounds
- ! create normalized humidity analysis variable.
- grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne) = &
- grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne)/qsat(:,:,nb,ne)
- enddo
- enddo
- endif
+ do ne=1,nanals_per_iotask
+ do nb=1,nbackgrounds
+ ! create normalized humidity analysis variable.
+ grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne) = &
+ grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne)/qsat(:,:,nb,ne)
+ enddo
+ enddo
end if
endif
@@ -296,6 +263,18 @@ subroutine write_control(no_inflate_flag)
if (nproc <= ntasks_io-1) then
+ ! scale q by ensemble qsat, prior to averaging
+ q_ind = getindex(cvars3d, 'q')
+ if (pseudo_rh .and. q_ind > 0) then
+ do ne=1,nanals_per_iotask
+ do nb=1,nbackgrounds
+ grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne) = &
+ grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne)*qsat(:,:,nb,ne)
+ enddo
+ enddo
+ endif
+
+
allocate(grdin_mean_tmp(npts,ncdim))
if (nproc == 0) then
allocate(grdin_mean(npts,ncdim,nbackgrounds,1))
@@ -342,34 +321,6 @@ subroutine write_control(no_inflate_flag)
100 format('ens. mean anal. increment min/max ',a,2x,g19.12,2x,g19.12)
deallocate(grdin_mean_tmp)
- q_ind = getindex(cvars3d, 'q')
- if (pseudo_rh .and. q_ind > 0) then
- if (use_qsatensmean) then
- do ne=1,nanals_per_iotask
- do nb=1,nbackgrounds
- ! re-scale normalized spfh with sat. sphf of ensmean first guess
- grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne) = &
- grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne)*qsatmean(:,:,nb)
- enddo
- enddo
- else
- do ne=1,nanals_per_iotask
- do nb=1,nbackgrounds
- ! re-scale normalized spfh with sat. sphf of first guess
- grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne) = &
- grdin(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,ne)*qsat(:,:,nb,ne)
- enddo
- enddo
- endif
- if (nproc == 0 .and. write_ensmean) then
- ! write_ensmean implies use_qsatensmean
- do nb=1,nbackgrounds
- ! re-scale normalized spfh with sat. sphf of ensmean first guess
- grdin_mean(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,1) = &
- grdin_mean(:,(q_ind-1)*nlevs+1:q_ind*nlevs,nb,1)*qsatmean(:,:,nb)
- enddo
- endif
- end if
if (.not. paranc) then
if (write_fv3_incr) then
call writeincrement(nanal1(nproc),nanal2(nproc),cvars3d,cvars2d,nc3d,nc2d,clevels,ncdim,grdin,no_inflate_flag)
@@ -410,7 +361,7 @@ subroutine write_control(no_inflate_flag)
endif
deallocate(grdin_mean)
t2 = mpi_wtime()
- print *,'time in write_control on root',t2-t1,'secs'
+ print *,'time in write_control paranc on root',t2-t1,'secs'
endif
end if
@@ -424,7 +375,6 @@ subroutine controlvec_cleanup()
if (allocated(index_pres)) deallocate(index_pres)
if (allocated(grdin)) deallocate(grdin)
if (allocated(qsat)) deallocate(qsat)
-if (allocated(qsatmean)) deallocate(qsatmean)
call gridinfo_cleanup()
end subroutine controlvec_cleanup
diff --git a/src/enkf/enkf.f90 b/src/enkf/enkf.f90
index c117e4ba56..479f60c019 100644
--- a/src/enkf/enkf.f90
+++ b/src/enkf/enkf.f90
@@ -51,7 +51,7 @@ module enkf
! NH, tropics and SH, and in the horizontal, vertical and time dimensions,
! using the namelist parameters corrlengthnh, corrlengthtr, corrlengthsh,
! lnsigcutoffnh, lnsigcutofftr, lnsigcutoffsh (lnsigcutoffsatnh,
-! lnsigcutoffsattr, lnsigcutoffsatsh for satellite obs, similar for ps obs)
+! lnsigcutoffsattr, lnsigcutoffsatsh for satellite obs, similar for ps and fed obs)
! obtimelnh, obtimeltr, obtimelsh. The length scales should be given in km for the
! horizontal, hours for time, and 'scale heights' (units of -log(p/pref)) in the
! vertical. The function used for localization (function taper)
@@ -97,6 +97,12 @@ module enkf
! used to be the same) and the "chunks" come from loadbal
! 2018-05-31: whitaker: add modulated ensemble model-space vertical
! localization (neigv>0) and denkf option.
+! 2022-04-01: Y. Wang and X. Wang: Add dbz_ind related if-blocks to fix spurious
+! analysis increments due to some unstable amplifying behaviors near edges of
+! strong precipitation when clear air and large reflectivity values are
+! assimilated in locations near each other (as may be the case in the leading
+! line of an MCS).
+! poc: xuguang.wang@ou.edu
!
! attributes:
! language: f95
@@ -182,7 +188,7 @@ subroutine enkf_update()
integer(i_kind) ierr
! kd-tree search results
type(kdtree2_result),dimension(:),allocatable :: sresults1,sresults2
-integer(i_kind) nanal,nn,nnn,nobm,nsame,nn1,nn2,oz_ind,nlev
+integer(i_kind) nanal,nn,nnn,nobm,nsame,nn1,nn2,oz_ind,nlev,dbz_ind
real(r_single),dimension(nlevs_pres):: taperv
logical lastiter, kdgrid, kdobs
@@ -609,6 +615,7 @@ subroutine enkf_update()
nn2 = ncdim
end if
if (nf2 > 0) then
+ dbz_ind = getindex(cvars3d, 'dbz')
!$omp parallel do schedule(dynamic,1) private(ii,i,nb,obt,nn,nnn,nlev,lnsig,kfgain,ens_tmp,taper1,taper3,taperv)
do ii=1,nf2 ! loop over nearby horiz grid points
do nb=1,nbackgrounds ! loop over background time levels
@@ -628,8 +635,13 @@ subroutine enkf_update()
! (through hpfhtcon)
kfgain=taper1*sum(ens_tmp*anal_obtmp_modens)
! update mean.
- ensmean_chunk(i,nn,nb) = ensmean_chunk(i,nn,nb) + &
- kfgain*obinc_tmp
+ if ( (nn >= (dbz_ind-1)*nlevs+1 .and. nn <= (dbz_ind-1)*nlevs+nlevs) )then
+ ensmean_chunk(i,nn,nb) = max(ensmean_chunk(i,nn,nb) + &
+ kfgain*obinc_tmp,zero)
+ else
+ ensmean_chunk(i,nn,nb) = ensmean_chunk(i,nn,nb) + &
+ kfgain*obinc_tmp
+ end if
! update perturbations.
anal_chunk(:,i,nn,nb) = anal_chunk(:,i,nn,nb) + &
kfgain*obganl(:)
@@ -652,7 +664,11 @@ subroutine enkf_update()
! (through hpfhtcon)
kfgain=taperv(nnn)*sum(anal_chunk(:,i,nn,nb)*anal_obtmp)
! update mean.
- ensmean_chunk(i,nn,nb) = ensmean_chunk(i,nn,nb) + kfgain*obinc_tmp
+ if ( (nn >= (dbz_ind-1)*nlevs+1 .and. nn <= (dbz_ind-1)*nlevs+nlevs) )then
+ ensmean_chunk(i,nn,nb) = max(ensmean_chunk(i,nn,nb) + kfgain*obinc_tmp,zero)
+ else
+ ensmean_chunk(i,nn,nb) = ensmean_chunk(i,nn,nb) + kfgain*obinc_tmp
+ end if
! update perturbations.
anal_chunk(:,i,nn,nb) = anal_chunk(:,i,nn,nb) + kfgain*obganl(:)
end if
@@ -681,7 +697,13 @@ subroutine enkf_update()
taper(obt*obtimelinv)* &
sum(anal_obchunk_modens(:,nob2)*anal_obtmp_modens)*hpfhtcon
! update mean.
- ensmean_obchunk(nob2) = ensmean_obchunk(nob2) + kfgain*obinc_tmp
+ nob3 = indxproc_obs(nproc+1,nob2)
+ if(trim(obtype(nob3)) == 'dbz' ) then
+ ensmean_obchunk(nob2) = max((ensmean_obchunk(nob2) + &
+ kfgain*obinc_tmp),zero)
+ else
+ ensmean_obchunk(nob2) = ensmean_obchunk(nob2) + kfgain*obinc_tmp
+ end if
! update perturbations.
anal_obchunk(:,nob2) = anal_obchunk(:,nob2) + kfgain*obganl
anal_obchunk_modens(:,nob2) = anal_obchunk_modens(:,nob2) + kfgain*obganl_modens
@@ -707,7 +729,13 @@ subroutine enkf_update()
taper(lnsig*lnsiglinv)*taper(obt*obtimelinv)* &
sum(anal_obchunk(:,nob2)*anal_obtmp)*hpfhtcon
! update mean.
- ensmean_obchunk(nob2) = ensmean_obchunk(nob2) + kfgain*obinc_tmp
+ nob3 = indxproc_obs(nproc+1,nob2)
+ if(trim(obtype(nob3)) == 'dbz' ) then
+ ensmean_obchunk(nob2) = max((ensmean_obchunk(nob2) + &
+ kfgain*obinc_tmp),zero)
+ else
+ ensmean_obchunk(nob2) = ensmean_obchunk(nob2) + kfgain*obinc_tmp
+ end if
! update perturbations.
anal_obchunk(:,nob2) = anal_obchunk(:,nob2) + kfgain*obganl
! recompute ob space spread ratio for unassimlated obs
@@ -758,6 +786,7 @@ subroutine enkf_update()
tend = mpi_wtime()
if (nproc .eq. 0) then
write(6,8003) niter,'timing on proc',nproc,' = ',tend-tbegin,t2,t3,t4,t5,t6,nrej
+ if(allocated(assimltd_flag))deallocate(assimltd_flag)
allocate(assimltd_flag(nobstot))
assimltd_flag = 99999
if (iassim_order == 2) then
diff --git a/src/enkf/enkf_obs_sensitivity.f90 b/src/enkf/enkf_obs_sensitivity.f90
index 6c37936f31..72296d5934 100644
--- a/src/enkf/enkf_obs_sensitivity.f90
+++ b/src/enkf/enkf_obs_sensitivity.f90
@@ -36,6 +36,7 @@ module enkf_obs_sensitivity
use params, only: efsoi_flag,latbound,nlevs,nanals,datestring, &
lnsigcutoffsatnh,lnsigcutoffsattr,lnsigcutoffsatsh, &
lnsigcutoffpsnh,lnsigcutoffpstr,lnsigcutoffpssh, &
+ lnsigcutofffednh,lnsigcutofffedtr,lnsigcutofffedsh, &
lnsigcutoffnh,lnsigcutofftr,lnsigcutoffsh, &
corrlengthnh,corrlengthtr,corrlengthsh, &
obtimelnh,obtimeltr,obtimelsh,letkf_flag, &
@@ -292,6 +293,8 @@ subroutine read_ob_sens
lnsigl(nob) = latval(deglat,lnsigcutoffsatnh,lnsigcutoffsattr,lnsigcutoffsatsh)
else if (obtype(nob)(1:3) == ' ps') then
lnsigl(nob) = latval(deglat,lnsigcutoffpsnh,lnsigcutoffpstr,lnsigcutoffpssh)
+ else if (obtype(nob)(1:3) == 'fed') then
+ lnsigl(nob) = latval(deglat,lnsigcutofffednh,lnsigcutofffedtr,lnsigcutofffedsh)
else
lnsigl(nob)=latval(deglat,lnsigcutoffnh,lnsigcutofftr,lnsigcutoffsh)
end if
diff --git a/src/enkf/enkf_obsmod.f90 b/src/enkf/enkf_obsmod.f90
index ba4b2946b1..eb4f9c8e58 100644
--- a/src/enkf/enkf_obsmod.f90
+++ b/src/enkf/enkf_obsmod.f90
@@ -109,6 +109,8 @@ module enkf_obsmod
lnsigcutoffnh, lnsigcutoffsh, lnsigcutofftr, corrlengthnh,&
corrlengthtr, corrlengthsh, obtimelnh, obtimeltr, obtimelsh,&
lnsigcutoffsatnh, lnsigcutoffsatsh, lnsigcutoffsattr,&
+ lnsigcutofffednh, lnsigcutofffedsh, lnsigcutofffedtr,&
+ corrlengthfednh, corrlengthfedtr, corrlengthfedsh, &
varqc, huber, zhuberleft, zhuberright, modelspace_vloc, &
lnsigcutoffpsnh, lnsigcutoffpssh, lnsigcutoffpstr, neigv, &
lnsigcutoffrdrnh, lnsigcutoffrdrsh, lnsigcutoffrdrtr,&
@@ -262,7 +264,6 @@ subroutine readobs()
allocate(corrlengthsq(nobstot),lnsigl(nobstot),obtimel(nobstot))
lnsigl=1.e10
do nob=1,nobstot
- oblnp(nob) = -log(obpress(nob)) ! distance measured in log(p) units
if (obloclon(nob) < zero) obloclon(nob) = obloclon(nob) + 360._r_single
radlon=deg2rad*obloclon(nob)
radlat=deg2rad*obloclat(nob)
@@ -277,16 +278,28 @@ subroutine readobs()
lnsigl(nob) = latval(deglat,lnsigcutoffsatnh,lnsigcutoffsattr,lnsigcutoffsatsh)
else if (obtype(nob)(1:3) == ' ps') then
lnsigl(nob) = latval(deglat,lnsigcutoffpsnh,lnsigcutoffpstr,lnsigcutoffpssh)
+ else if (obtype(nob)(1:3) == 'fed') then
+ lnsigl(nob) = latval(deglat,lnsigcutofffednh,lnsigcutofffedtr,lnsigcutofffedsh)
else if ( (obtype(nob)(1:3) == 'dbz' .or. obtype(nob)(1:3) == ' rw') .and. l_use_enkf_directZDA ) then
lnsigl(nob) = latval(deglat,lnsigcutoffrdrnh,lnsigcutoffrdrtr,lnsigcutoffrdrsh)
else
lnsigl(nob)=latval(deglat,lnsigcutoffnh,lnsigcutofftr,lnsigcutoffsh)
end if
endif
+ ! total column ozone has pressure set to zero, set to 0.001Pa
+ ! and turn vertical localization off (no effect if modelspace_vloc=T)
+ if (obpress(nob) < 0.001 .and. obtype(nob)(1:3) .eq. ' oz') then
+ lnsigl(nob) = 1.e30 ! turn ob-space vert localization off
+ obpress(nob) = 0.001 ! set to a non-zero value
+ endif
+ oblnp(nob) = -log(obpress(nob)) ! distance measured in log(p) units
corrlengthsq(nob)=latval(deglat,corrlengthnh,corrlengthtr,corrlengthsh)**2
if ( (obtype(nob)(1:3) == 'dbz' .or. obtype(nob)(1:3) == ' rw') .and. l_use_enkf_directZDA ) then
corrlengthsq(nob)=latval(deglat,corrlengthrdrnh,corrlengthrdrtr,corrlengthrdrsh)**2
end if
+ if (obtype(nob)(1:3) == 'fed') then
+ corrlengthsq(nob)=latval(deglat,corrlengthfednh,corrlengthfedtr,corrlengthfedsh)**2
+ end if
obtimel(nob)=latval(deglat,obtimelnh,obtimeltr,obtimelsh)
end do
diff --git a/src/enkf/gridinfo_fv3reg.f90 b/src/enkf/gridinfo_fv3reg.f90
index 53e5f5b3de..337c9ba682 100644
--- a/src/enkf/gridinfo_fv3reg.f90
+++ b/src/enkf/gridinfo_fv3reg.f90
@@ -43,10 +43,12 @@ module gridinfo
!
!$$$
-use mpisetup, only: nproc, mpi_integer, mpi_real4, mpi_comm_world,mpi_status
+use mpisetup, only: nproc, mpi_integer, mpi_real4,mpi_status
+use mpimod, only: mpi_comm_world
use params, only: datapath,nlevs,nlons,nlats,use_gfs_nemsio, fgfileprefixes, &
fv3fixpath, nx_res,ny_res, ntiles,l_fv3reg_filecombined,paranc, &
- fv3_io_layout_nx,fv3_io_layout_ny
+ fv3_io_layout_nx,fv3_io_layout_ny,taperanalperts,taperanalperts_akbot, &
+ taperanalperts_aktop
use kinds, only: r_kind, i_kind, r_double, r_single
use constants, only: one,zero,pi,cp,rd,grav,rearth,max_varname_length
@@ -64,6 +66,7 @@ module gridinfo
public :: ak,bk,eta1_ll,eta2_ll
real(r_single),public :: ptop
real(r_single),public, allocatable, dimension(:) :: lonsgrd, latsgrd
+real(r_single),public, allocatable, dimension(:) :: taper_vert
! arrays passed to kdtree2 routines must be single
real(r_single),public, allocatable, dimension(:,:) :: gridloc
real(r_single),public, allocatable, dimension(:,:) :: logp
@@ -71,13 +74,15 @@ module gridinfo
integer(i_kind),public :: npts
integer(i_kind),public :: ntrunc
! supported variable names in anavinfo
-character(len=max_varname_length),public, dimension(15) :: &
+character(len=max_varname_length),public, dimension(16) :: &
vars3d_supported = [character(len=max_varname_length) :: &
'u', 'v', 'w', 't', 'q', 'oz', 'cw', 'tsen', 'prse', &
- 'ql', 'qi', 'qr', 'qs', 'qg', 'qnr']
+ 'ql', 'qi', 'qr', 'qs', 'qg', 'qnr','dbz']
character(len=max_varname_length),public, dimension(3) :: &
vars2d_supported = [character(len=max_varname_length) :: &
'ps', 'pst', 'sst']
+character(len=max_varname_length),public, dimension(8) :: &
+ vars2d_landonly = (/'', '', '', '', '', '', '', '' /)
real(r_single), allocatable, dimension(:) :: ak,bk,eta1_ll,eta2_ll
integer (i_kind),public,allocatable,dimension(:,:):: nxlocgroup,nylocgroup
integer(i_kind):: numproc_io_sub
@@ -130,7 +135,7 @@ subroutine getgridinfo(fileprefix, reducedgrid)
!when paranc=.false, fv3_io_layout_nx=fv3_io_layout_ny=1
! read data on root task
-if (nproc .eq. 0) then
+if (nproc == 0) then
! read ak,bk from ensmean fv_core.res.nc
! read nx,ny and nz from fv_core.res.nc
@@ -161,19 +166,35 @@ subroutine getgridinfo(fileprefix, reducedgrid)
eta2_ll(i)=bk(i)
enddo
-
-
-
ptop = eta1_ll(nlevsp1)
call nc_check( nf90_close(file_id),&
myname_,'close '//trim(filename) )
+
+ ! vertical taper function for ens perts
+ allocate(taper_vert(nlevs))
+ if (taperanalperts) then
+ do k=1,nlevs
+ if (k < nlevs/2 .and. (ak(k) <= taperanalperts_akbot .and. ak(k) >= taperanalperts_aktop)) then
+ taper_vert(nlevs-k+1)= log(ak(k) - taperanalperts_aktop)/log(taperanalperts_akbot - taperanalperts_aktop)
+ else if (bk(k) == zero .and. ak(k) < taperanalperts_aktop) then
+ taper_vert(nlevs-k+1) = zero
+ endif
+ enddo
+ print *,'vertical taper for anal perts:'
+ do k=1,nlevs
+ print *,k,ak(nlevs-k+1),bk(nlevs-k+1),taper_vert(k)
+ enddo
+ else
+ taper_vert = one
+ endif
+
deallocate(ak,bk)
endif ! root task
allocate(nxlocgroup(fv3_io_layout_nx,fv3_io_layout_ny))
allocate(nylocgroup(fv3_io_layout_nx,fv3_io_layout_ny))
-if(nproc.eq.0) then
+if(nproc == 0) then
ii=0
do j=1,fv3_io_layout_ny
do i=1,fv3_io_layout_nx
@@ -460,7 +481,7 @@ subroutine getgridinfo(fileprefix, reducedgrid)
allocate(gridloc(3,npts))
if (nproc .ne. 0) then
! allocate arrays on other (non-root) tasks
- allocate(latsgrd(npts),lonsgrd(npts))
+ allocate(latsgrd(npts),lonsgrd(npts),taper_vert(nlevs))
allocate(logp(npts,nlevs_pres)) ! log(ens mean first guess press) on mid-layers
allocate(eta1_ll(nlevsp1),eta2_ll(nlevsp1))
endif
@@ -470,6 +491,7 @@ subroutine getgridinfo(fileprefix, reducedgrid)
enddo
call mpi_bcast(lonsgrd,npts,mpi_real4,0,MPI_COMM_WORLD,ierr)
call mpi_bcast(latsgrd,npts,mpi_real4,0,MPI_COMM_WORLD,ierr)
+call mpi_bcast(taper_vert,nlevs,mpi_real4,0,MPI_COMM_WORLD,ierr)
call mpi_bcast(eta1_ll,nlevsp1,mpi_real4,0,MPI_COMM_WORLD,ierr)
call mpi_bcast(eta2_ll,nlevsp1,mpi_real4,0,MPI_COMM_WORLD,ierr)
call mpi_bcast(ptop,1,mpi_real4,0,MPI_COMM_WORLD,ierr)
@@ -486,6 +508,7 @@ end subroutine getgridinfo
subroutine gridinfo_cleanup()
if (allocated(lonsgrd)) deallocate(lonsgrd)
if (allocated(latsgrd)) deallocate(latsgrd)
+if (allocated(taper_vert)) deallocate(taper_vert)
if (allocated(logp)) deallocate(logp)
if (allocated(gridloc)) deallocate(gridloc)
end subroutine gridinfo_cleanup
diff --git a/src/enkf/gridinfo_gfs.f90 b/src/enkf/gridinfo_gfs.f90
index c2e2b10f57..efbd7a2959 100644
--- a/src/enkf/gridinfo_gfs.f90
+++ b/src/enkf/gridinfo_gfs.f90
@@ -45,7 +45,8 @@ module gridinfo
use mpisetup, only: nproc, mpi_integer, mpi_real4
use mpimod, only: mpi_comm_world
-use params, only: datapath,nlevs,nlons,nlats,use_gfs_nemsio,use_gfs_ncio,fgfileprefixes
+use params, only: datapath,nlevs,nlons,nlats,use_gfs_nemsio,use_gfs_ncio,fgfileprefixes,&
+ taperanalperts,taperanalperts_aktop,taperanalperts_akbot
use kinds, only: r_kind, i_kind, r_double, r_single
use constants, only: one,zero,pi,cp,rd,grav,rearth,max_varname_length
use specmod, only: sptezv_s, sptez_s, init_spec_vars, isinitialized, asin_gaulats, &
@@ -57,7 +58,7 @@ module gridinfo
public :: getgridinfo, gridinfo_cleanup
integer(i_kind),public :: nlevs_pres, idvc
real(r_single),public :: ptop
-real(r_single),public, allocatable, dimension(:) :: lonsgrd, latsgrd
+real(r_single),public, allocatable, dimension(:) :: lonsgrd, latsgrd, taper_vert
! arrays passed to kdtree2 routines must be single
real(r_single),public, allocatable, dimension(:,:) :: gridloc
real(r_single),public, allocatable, dimension(:,:) :: logp
@@ -66,7 +67,8 @@ module gridinfo
! supported variable names in anavinfo
character(len=max_varname_length),public, dimension(13) :: vars3d_supported = (/'u ', 'v ', 'tv ', 'q ', 'oz ', 'cw ', 'tsen', 'prse', &
'ql ', 'qi ', 'qr ', 'qs ', 'qg '/)
-character(len=max_varname_length),public, dimension(3) :: vars2d_supported = (/'ps ', 'pst', 'sst' /)
+character(len=max_varname_length),public, dimension(13) :: vars2d_supported = (/'ps ', 'pst', 'sst', 't2m', 'q2m', 'st1', 'st2', 'st3', 'st4', 'sl1', 'sl2', 'sl3', 'sl4' /)
+character(len=max_varname_length),public, dimension(8) :: vars2d_landonly = (/'st1', 'st2', 'st3', 'st4', 'sl1', 'sl2', 'sl3', 'sl4' /)
! supported variable names in anavinfo
contains
@@ -104,7 +106,7 @@ subroutine getgridinfo(fileprefix, reducedgrid)
kapr = cp/rd
kap1 = kap + one
nlevs_pres=nlevs+1
-if (nproc .eq. 0) then
+if (nproc == 0) then
filename = trim(adjustl(datapath))//trim(adjustl(fileprefix))//"ensmean"
if (use_gfs_nemsio) then
call nemsio_init(iret=iret)
@@ -167,11 +169,13 @@ subroutine getgridinfo(fileprefix, reducedgrid)
! initialize spectral module on all tasks.
if (.not. isinitialized) call init_spec_vars(nlons,nlats,ntrunc,4)
-if (nproc .eq. 0) then
+if (nproc == 0) then
! get pressure, lat/lon information from ensemble mean file.
allocate(presslmn(nlons*nlats,nlevs))
allocate(pressimn(nlons*nlats,nlevs+1))
allocate(spressmn(nlons*nlats))
+ allocate(taper_vert(nlevs))
+ taper_vert=one
if (use_gfs_nemsio) then
call nemsio_readrecv(gfile,'pres','sfc',1,nems_wrk,iret=iret)
if (iret/=0) then
@@ -220,7 +224,6 @@ subroutine getgridinfo(fileprefix, reducedgrid)
enddo
call nemsio_close(gfile, iret=iret)
ptop = ak(nlevs+1)
- deallocate(ak,bk)
else if (use_gfs_ncio) then
call read_vardata(dset, 'pressfc', values_2d,errcode=iret)
if (iret /= 0) then
@@ -237,7 +240,7 @@ subroutine getgridinfo(fileprefix, reducedgrid)
pressimn(:,k) = 0.01_r_kind*ak(nlevs-k+2)+bk(nlevs-k+2)*spressmn(:)
enddo
ptop = 0.01_r_kind*ak(1)
- deallocate(ak,bk,values_2d)
+ deallocate(values_2d)
else
! get pressure from ensemble mean,
! distribute to all processors.
@@ -277,7 +280,6 @@ subroutine getgridinfo(fileprefix, reducedgrid)
enddo
call sigio_axdata(sigdata,iret)
ptop = ak(nlevs+1)
- deallocate(ak,bk)
endif
if (reducedgrid) then
call reducedgrid_init(nlons,nlats,asin_gaulats)
@@ -333,11 +335,28 @@ subroutine getgridinfo(fileprefix, reducedgrid)
logp(:,nlevs_pres) = -log(spressmn(:))
endif
deallocate(spressmn,presslmn,pressimn)
+ ! vertical taper function for ens perts
+ if (taperanalperts) then
+ do k=1,nlevs
+ if (k < nlevs/2 .and. (ak(k) <= taperanalperts_akbot .and. ak(k) >= taperanalperts_aktop)) then
+ taper_vert(nlevs-k+1)= log(ak(k) - taperanalperts_aktop)/log(taperanalperts_akbot - taperanalperts_aktop)
+ else if (bk(k) == zero .and. ak(k) < taperanalperts_aktop) then
+ taper_vert(nlevs-k+1) = zero
+ endif
+ enddo
+ print *,'vertical taper for anal perts:'
+ do k=1,nlevs
+ print *,k,ak(nlevs-k+1),bk(nlevs-k+1),taper_vert(k)
+ enddo
+ endif
+ if (allocated(ak)) deallocate(ak)
+ if (allocated(bk)) deallocate(bk)
end if
call mpi_bcast(npts,1,MPI_INTEGER,0,MPI_COMM_WORLD,ierr)
if (nproc .ne. 0) then
! allocate arrays on other (non-root) tasks
allocate(latsgrd(npts),lonsgrd(npts))
+ allocate(taper_vert(nlevs))
allocate(logp(npts,nlevs_pres)) ! log(ens mean first guess press) on mid-layers
allocate(gridloc(3,npts))
! initialize reducedgrid_mod on other tasks.
@@ -351,6 +370,7 @@ subroutine getgridinfo(fileprefix, reducedgrid)
enddo
call mpi_bcast(lonsgrd,npts,mpi_real4,0,MPI_COMM_WORLD,ierr)
call mpi_bcast(latsgrd,npts,mpi_real4,0,MPI_COMM_WORLD,ierr)
+call mpi_bcast(taper_vert,nlevs,mpi_real4,0,MPI_COMM_WORLD,ierr)
call mpi_bcast(ptop,1,mpi_real4,0,MPI_COMM_WORLD,ierr)
!==> precompute cartesian coords of analysis grid points.
do nn=1,npts
@@ -364,6 +384,7 @@ end subroutine getgridinfo
subroutine gridinfo_cleanup()
if (allocated(lonsgrd)) deallocate(lonsgrd)
if (allocated(latsgrd)) deallocate(latsgrd)
+if (allocated(taper_vert)) deallocate(taper_vert)
if (allocated(logp)) deallocate(logp)
if (allocated(gridloc)) deallocate(gridloc)
end subroutine gridinfo_cleanup
diff --git a/src/enkf/gridinfo_nmmb.f90 b/src/enkf/gridinfo_nmmb.f90
index d60b077f36..33b487354e 100644
--- a/src/enkf/gridinfo_nmmb.f90
+++ b/src/enkf/gridinfo_nmmb.f90
@@ -1,6 +1,7 @@
module gridinfo
-use mpisetup
+use mpisetup, only: nproc, mpi_integer, mpi_real4
+use mpimod, only: mpi_comm_world
use params, only: datapath,nlevs,datestring,&
nmmb,regional,nlons,nlats,nbackgrounds,fgfileprefixes
use kinds, only: r_kind, i_kind, r_double, r_single
@@ -16,6 +17,7 @@ module gridinfo
integer(i_kind),public :: nlevs_pres
real(r_single),public :: ptop
real(r_single),public, allocatable, dimension(:) :: lonsgrd, latsgrd
+real(r_single),public, allocatable, dimension(:) :: taper_vert
! arrays passed to kdtree2 routines must be single
real(r_single),public, allocatable, dimension(:,:) :: gridloc
real(r_single),public, allocatable, dimension(:,:) :: logp
@@ -25,6 +27,8 @@ module gridinfo
'cw', 'prse', 'ql', 'qr', 'qi', &
'qli', 'dbz', 'w'/)
character(len=max_varname_length),public, dimension(2) :: vars2d_supported = (/ 'ps', 'sst' /)
+character(len=max_varname_length),public, dimension(8) :: vars2d_landonly = (/'', '', '', '', '', '', '', '' /)
+
contains
subroutine getgridinfo(fileprefix, reducedgrid)
@@ -122,6 +126,8 @@ subroutine getgridinfo(fileprefix, reducedgrid)
allocate(latsgrd(npts),lonsgrd(npts))
allocate(logp(npts,nlevs_pres)) ! log(ens mean first guess press) on mid-layers
allocate(gridloc(3,npts))
+ allocate(taper_vert(nlevs))
+ taper_vert=one
lonsgrd = lons; latsgrd = lats
print *,'min/max lonsgrd',minval(lonsgrd),maxval(lonsgrd)
print *,'min/max latsgrd',minval(latsgrd),maxval(latsgrd)
@@ -163,6 +169,7 @@ subroutine getgridinfo(fileprefix, reducedgrid)
if (nproc .ne. 0) then
! allocate arrays on other (non-root) tasks
allocate(latsgrd(npts),lonsgrd(npts))
+ allocate(taper_vert(nlevs))
allocate(logp(npts,nlevs_pres)) ! log(ens mean first guess press) on mid-layers
allocate(gridloc(3,npts))
endif
@@ -172,6 +179,7 @@ subroutine getgridinfo(fileprefix, reducedgrid)
enddo
call mpi_bcast(lonsgrd,npts,mpi_real4,0,MPI_COMM_WORLD,ierr)
call mpi_bcast(latsgrd,npts,mpi_real4,0,MPI_COMM_WORLD,ierr)
+call mpi_bcast(taper_vert,nlevs,mpi_real4,0,MPI_COMM_WORLD,ierr)
call mpi_bcast(ptop,1,mpi_real4,0,MPI_COMM_WORLD,ierr)
!==> precompute cartesian coords of analysis grid points.
@@ -186,6 +194,7 @@ end subroutine getgridinfo
subroutine gridinfo_cleanup()
if (allocated(lonsgrd)) deallocate(lonsgrd)
if (allocated(latsgrd)) deallocate(latsgrd)
+if (allocated(taper_vert)) deallocate(taper_vert)
if (allocated(logp)) deallocate(logp)
if (allocated(gridloc)) deallocate(gridloc)
end subroutine gridinfo_cleanup
diff --git a/src/enkf/gridinfo_wrf.f90 b/src/enkf/gridinfo_wrf.f90
index f4f68a64c4..4ad80aaa60 100644
--- a/src/enkf/gridinfo_wrf.f90
+++ b/src/enkf/gridinfo_wrf.f90
@@ -32,12 +32,13 @@ module gridinfo
! Define associated modules
- use constants, only: rearth_equator, omega, pi, deg2rad, zero, rad2deg, &
+ use constants, only: rearth_equator, omega, pi, deg2rad, zero, one, rad2deg, &
rearth,max_varname_length
use kinds, only: i_kind, r_kind, r_single, i_long, r_double
use params, only: datapath, nlevs, nlons, nlats, &
arw, nmm
- use mpisetup
+ use mpisetup, only: nproc, mpi_integer, mpi_real4,mpi_status
+ use mpimod, only: mpi_comm_world
use netcdf_io
implicit none
@@ -63,6 +64,7 @@ module gridinfo
real(r_single), dimension(:,:), allocatable, public :: gridloc
real(r_single), dimension(:), allocatable, public :: lonsgrd
real(r_single), dimension(:), allocatable, public :: latsgrd
+ real(r_single), dimension(:), allocatable, public :: taper_vert
real(r_single), public :: ptop
integer(i_long), public :: npts
integer(i_kind), public :: nlevs_pres
@@ -77,6 +79,8 @@ module gridinfo
! supported variable names in anavinfo
character(len=max_varname_length),public, dimension(19) :: vars3d_supported = (/'u ', 'v ', 'tv ', 'q ', 'w ', 'cw ', 'ph ', 'ql ', 'qr ', 'qs ', 'qg ', 'qi ', 'qni ', 'qnr ', 'qnc ', 'dbz ', 'oz ', 'tsen', 'prse' /)
character(len=max_varname_length),public, dimension(2) :: vars2d_supported = (/ 'ps ', 'sst' /)
+ character(len=max_varname_length),public, dimension(8) :: vars2d_landonly = (/'', '', '', '', '', '', '', '' /)
+
contains
@@ -209,7 +213,9 @@ subroutine getgridinfo_arw(fileprefix)
! Allocate memory for global arrays
if(.not. allocated(lonsgrd)) allocate(lonsgrd(npts))
if(.not. allocated(latsgrd)) allocate(latsgrd(npts))
+ if(.not. allocated(taper_vert)) allocate(taper_vert(nlevs))
if(.not. allocated(logp)) allocate(logp(npts,nlevs_pres))
+ taper_vert = one
!======================================================================
! Begin: Ingest all grid variables required for EnKF routines and
@@ -846,6 +852,7 @@ end subroutine dot2cross
subroutine gridinfo_cleanup()
if (allocated(lonsgrd)) deallocate(lonsgrd)
if (allocated(latsgrd)) deallocate(latsgrd)
+ if (allocated(taper_vert)) deallocate(taper_vert)
if (allocated(logp)) deallocate(logp)
if (allocated(gridloc)) deallocate(gridloc)
end subroutine gridinfo_cleanup
diff --git a/src/enkf/gridio_fv3reg.f90 b/src/enkf/gridio_fv3reg.f90
index fb23a21a0c..068e6cba8b 100644
--- a/src/enkf/gridio_fv3reg.f90
+++ b/src/enkf/gridio_fv3reg.f90
@@ -24,6 +24,8 @@ module gridio
! -- add code to update 'delp' directly
! from analysis icnrements
! 2022-06- Ting -- Implement paranc=.true. for fv3-lam
+ ! 2022-04-01 Yongming Wang and X. Wang: Add interface for read in dBZ
+ ! poc: xuguang.wang@ou.edu
! attributes:
! language: f95
!
@@ -40,7 +42,7 @@ module gridio
use params, only: nlevs, cliptracers, datapath, arw, nmm, datestring
use params, only: nx_res,ny_res,nlevs,ntiles,l_fv3reg_filecombined,&
fv3_io_layout_nx,fv3_io_layout_ny,nanals
- use params, only: pseudo_rh, l_use_enkf_directZDA
+ use params, only: pseudo_rh
use mpeu_util, only: getindex
use read_fv3regional_restarts,only:read_fv3_restart_data1d,read_fv3_restart_data2d
use read_fv3regional_restarts,only:read_fv3_restart_data3d,read_fv3_restart_data4d
@@ -60,17 +62,19 @@ module gridio
!-------------------------------------------------------------------------
- integer(i_kind) ,parameter:: ndynvarslist=6, ntracerslist=8
+ integer(i_kind) ,parameter:: ndynvarslist=6, ntracerslist=8, nphysicslist=1
character(len=max_varname_length), parameter, dimension(ndynvarslist) :: &
vardynvars = [character(len=max_varname_length) :: &
'u', 'v', 'T', 'W', 'DZ', 'delp']
character(len=max_varname_length), parameter, dimension(ntracerslist) :: &
vartracers = [character(len=max_varname_length) :: &
'sphum','o3mr', 'liq_wat','ice_wat','rainwat','snowwat','graupel','rain_nc']
+ character(len=max_varname_length), parameter, dimension(nphysicslist) :: &
+ varphysics = [character(len=max_varname_length) :: 'ref_f3d']
type type_fv3lamfile
logical l_filecombined
- character(len=max_varname_length), dimension(2):: fv3lamfilename
- integer (i_kind), dimension(2):: fv3lam_fileid(2)
+ character(len=max_varname_length), dimension(3):: fv3lamfilename
+ integer (i_kind), dimension(3):: fv3lam_fileid
contains
procedure, pass(this) :: setupfile => type_bound_setupfile
procedure, pass(this):: get_idfn => type_bound_getidfn
@@ -104,9 +108,9 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
! Define local variables
character(len=500) :: filename
- character(len=:),allocatable :: fv3filename,fv3filename1
+ character(len=:),allocatable :: fv3filename,fv3filename1,fv3filename2
character(len=7) :: charnanal
- integer(i_kind) file_id,file_id1
+ integer(i_kind) file_id,file_id1,file_id2
real(r_single), dimension(:,:,:), allocatable ::workvar3d,uworkvar3d,&
vworkvar3d,tvworkvar3d,tsenworkvar3d,&
workprsi,qworkvar3d
@@ -124,6 +128,7 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
integer(i_kind) :: nlevsp1
integer (i_kind):: i,j, k,nn,ntile,nn_tile0, nb,nanal,ne
integer(i_kind) :: u_ind, v_ind, tv_ind,tsen_ind, q_ind, oz_ind
+ integer(i_kind) :: dbz_ind
integer(i_kind) :: w_ind, ql_ind, qi_ind, qr_ind, qs_ind, qg_ind, qnr_ind
integer (i_kind):: ps_ind, sst_ind
integer (i_kind):: tmp_ind,ifile
@@ -147,6 +152,7 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
qs_ind = getindex(vars3d, 'qs') ! Q snow (3D)
qg_ind = getindex(vars3d, 'qg') ! Q graupel (3D)
qnr_ind = getindex(vars3d, 'qnr') ! N rain (3D)
+ dbz_ind = getindex(vars3d, 'dbz') ! Reflectivity (3D)
ps_ind = getindex(vars2d, 'ps') ! Ps (2D)
sst_ind = getindex(vars2d, 'sst') ! SST (2D)
@@ -191,9 +197,19 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
fv3filename1=trim(adjustl(filename))//"_tracer"
call nc_check( nf90_open(trim(adjustl(fv3filename1)),nf90_nowrite,file_id1),&
myname_,'open: '//trim(adjustl(fv3filename1)) )
- call fv3lamfile%setupfile(fileid1=file_id,fv3fn1=trim(adjustl(fv3filename)) , &
- fileid2=file_id1,fv3fn2=trim(adjustl(fv3filename1)) )
-
+ if(dbz_ind > 0) then
+ fv3filename2=trim(adjustl(filename))//"_phyvar"
+ call nc_check(nf90_open(trim(adjustl(fv3filename2)),nf90_nowrite,file_id2),&
+ myname_,'open: '//trim(adjustl(fv3filename2)) )
+ endif
+ if(dbz_ind > 0) then
+ call fv3lamfile%setupfile(fileid1=file_id,fv3fn1=trim(adjustl(fv3filename)) , &
+ fileid2=file_id1,fv3fn2=trim(adjustl(fv3filename1)),&
+ fileid3=file_id2,fv3fn3=trim(adjustl(fv3filename2)))
+ else
+ call fv3lamfile%setupfile(fileid1=file_id,fv3fn1=trim(adjustl(fv3filename)) , &
+ fileid2=file_id1,fv3fn2=trim(adjustl(fv3filename1)))
+ endif
endif
!----------------------------------------------------------------------
@@ -476,6 +492,27 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
endif
+ if (dbz_ind > 0) then
+ varstrname = 'ref_f3d'
+ call fv3lamfile%get_idfn(varstrname,file_id,fv3filename)
+ call read_fv3_restart_data3d(varstrname,fv3filename,file_id,workvar3d)
+ do k=1,nlevs
+ nn = nn_tile0
+ do j=1,ny_res
+ do i=1,nx_res
+ nn=nn+1
+ vargrid(nn,levels(dbz_ind-1)+k,nb,ne)=max(workvar3d(i,j,nlevs+1-k),0.0_r_kind)
+ enddo
+ enddo
+ enddo
+ do k = levels(dbz_ind-1)+1, levels(dbz_ind)
+ if (nproc .eq. 0) &
+ write(6,*) 'READFVregional : dbz ', &
+ & k, minval(vargrid(:,k,nb,ne)), maxval(vargrid(:,k,nb,ne))
+ enddo
+
+ endif
+
! set SST to zero for now
if (sst_ind > 0) then
vargrid(:,levels(n3d)+sst_ind,nb,ne) = zero
@@ -549,7 +586,8 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
call nc_check( nf90_close(file_id),&
myname_,'close '//trim(filename) )
else
- do ifile=1,2
+ do ifile=1,3
+ if(dbz_ind <= 0 .and. ifile == 3) cycle
file_id=fv3lamfile%fv3lam_fileid(ifile)
filename=fv3lamfile%fv3lamfilename(ifile)
call nc_check( nf90_close(file_id),&
@@ -601,15 +639,15 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
!----------------------------------------------------------------------
! Define variables computed within subroutine
character(len=500) :: filename
- character(len=:),allocatable :: fv3filename,fv3filename1
+ character(len=:),allocatable :: fv3filename,fv3filename1,fv3filename2
character(len=7) :: charnanal
!----------------------------------------------------------------------
- integer(i_kind) :: u_ind, v_ind, tv_ind, tsen_ind,q_ind, ps_ind,oz_ind
- integer(i_kind) :: w_ind
+ integer(i_kind) :: u_ind, v_ind, tv_ind, tsen_ind,q_ind, ps_ind,oz_ind,dbz_ind
+ integer(i_kind) :: w_ind, cw_ind, ph_ind
integer(i_kind) :: ql_ind, qi_ind, qr_ind, qs_ind, qg_ind, qnr_ind
- integer(i_kind) file_id,file_id1
+ integer(i_kind) file_id,file_id1,file_id2
real(r_single), dimension(:,:), allocatable ::pswork
real(r_single), dimension(:,:,:), allocatable ::workvar3d,workinc3d,workinc3d2,uworkvar3d,&
vworkvar3d,tvworkvar3d,tsenworkvar3d,&
@@ -652,10 +690,11 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
qs_ind = getindex(vars3d, 'qs') ! QS (3D) for FV3
qg_ind = getindex(vars3d, 'qg') ! QG (3D) for FV3
qnr_ind = getindex(vars3d, 'qnr') ! QNR (3D) for FV3
+ dbz_ind = getindex(vars3d, 'dbz') ! Reflectivity (3D)
ps_ind = getindex(vars2d, 'ps') ! Ps (2D)
-
+ clip=tiny(clip)
!----------------------------------------------------------------------
if (nbackgrounds > 1) then
write(6,*)'gridio/writegriddata: writing multiple backgrounds not yet supported'
@@ -699,6 +738,15 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
call fv3lamfile%setupfile(fileid1=file_id,fv3fn1=trim(adjustl(fv3filename)) , &
fileid2=file_id1,fv3fn2=trim(adjustl(fv3filename1)) )
+ if(dbz_ind > 0) then
+ call fv3lamfile%setupfile(fileid1=file_id,fv3fn1=trim(adjustl(fv3filename)) , &
+ fileid2=file_id1,fv3fn2=trim(adjustl(fv3filename1)),&
+ fileid3=file_id2,fv3fn3=trim(adjustl(fv3filename2)))
+ else
+ call fv3lamfile%setupfile(fileid1=file_id,fv3fn1=trim(adjustl(fv3filename)) , &
+ fileid2=file_id1,fv3fn2=trim(adjustl(fv3filename1)))
+ endif
+
endif
@@ -805,6 +853,8 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
varstrname = 'sphum'
call fv3lamfile%get_idfn(varstrname,file_id,fv3filename)
call read_fv3_restart_data3d(varstrname,fv3filename,file_id,qworkvar3d)
+ !enforce lower positive bound (clip) to replace negative hydrometers
+ if ( cliptracers ) where (qworkvar3d < clip) qworkvar3d = clip
tvworkvar3d=tsenworkvar3d*(one+fv*qworkvar3d)
tvworkvar3d=tvworkvar3d+workinc3d
if(q_ind > 0) then
@@ -818,6 +868,8 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
enddo
enddo
qworkvar3d=qworkvar3d+workinc3d
+ !enforce lower positive bound (clip) to replace negative q
+ if ( cliptracers ) where (qworkvar3d < clip) qworkvar3d = clip
endif
tsenworkvar3d=tvworkvar3d/(one+fv*qworkvar3d)
varstrname = 'T'
@@ -884,10 +936,7 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
call write_fv3_restart_data3d(varstrname,fv3filename,file_id,workvar3d)
endif
@@ -907,10 +956,7 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
call write_fv3_restart_data3d(varstrname,fv3filename,file_id,workvar3d)
endif
@@ -930,10 +976,7 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
call write_fv3_restart_data3d(varstrname,fv3filename,file_id,workvar3d)
endif
@@ -953,10 +996,7 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
call write_fv3_restart_data3d(varstrname,fv3filename,file_id,workvar3d)
endif
@@ -976,10 +1016,7 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
call write_fv3_restart_data3d(varstrname,fv3filename,file_id,workvar3d)
endif
@@ -998,10 +1035,26 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
+ call write_fv3_restart_data3d(varstrname,fv3filename,file_id,workvar3d)
+
+ endif
+
+ if (dbz_ind > 0) then
+ varstrname = 'ref_f3d'
+ call fv3lamfile%get_idfn(varstrname,file_id,fv3filename)
+ call read_fv3_restart_data3d(varstrname,fv3filename,file_id,workvar3d)
+ do k=1,nlevs
+ nn = nn_tile0
+ do j=1,ny_res
+ do i=1,nx_res
+ nn=nn+1
+ workinc3d(i,j,nlevs+1-k)=vargrid(nn,levels(dbz_ind-1)+k,nb,ne)
+ enddo
+ enddo
+ enddo
+ workvar3d=workvar3d+workinc3d
+ where (workvar3d < 0.0_r_kind) workvar3d = 0.0_r_kind
call write_fv3_restart_data3d(varstrname,fv3filename,file_id,workvar3d)
endif
@@ -1051,7 +1104,8 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,vargrid
call nc_check( nf90_close(file_id),&
myname_,'close '//trim(filename) )
else
- do ifile=1,2
+ do ifile=1,3
+ if(dbz_ind <=0 .and. ifile == 3) cycle
file_id=fv3lamfile%fv3lam_fileid(ifile)
filename=fv3lamfile%fv3lamfilename(ifile)
call nc_check( nf90_close(file_id),&
@@ -1820,7 +1874,7 @@ subroutine writegriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,vargrid,no_inflat
ps_ind = getindex(vars2d, 'ps') ! Ps (2D)
-
+ clip=tiny(clip)
allocate(my_neb(4))
!----------------------------------------------------------------------
if (nbackgrounds > 1) then
@@ -2105,6 +2159,7 @@ subroutine writegriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,vargrid,no_inflat
enddo
if(iope ==0 ) then
+ if ( cliptracers ) where (qworkvar3d < clip) qworkvar3d = clip
tvworkvar3d=tsenworkvar3d*(one+fv*qworkvar3d)
tvworkvar3d=tvworkvar3d+workinc3d
if(q_ind > 0) then
@@ -2118,6 +2173,7 @@ subroutine writegriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,vargrid,no_inflat
enddo
enddo
qworkvar3d=qworkvar3d+workinc3d
+ if ( cliptracers ) where (qworkvar3d < clip) qworkvar3d = clip
endif
tsenworkvar3d=tvworkvar3d/(one+fv*qworkvar3d)
endif
@@ -2213,10 +2269,7 @@ subroutine writegriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,vargrid,no_inflat
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
endif
do k=1,nlevs
call mpi_scatterv(workvar3d(:,:,k),recvcounts2d,displs2d,mpi_real4,&
@@ -2247,10 +2300,7 @@ subroutine writegriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,vargrid,no_inflat
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
endif
do k=1,nlevs
call mpi_scatterv(workvar3d(:,:,k),recvcounts2d,displs2d,mpi_real4,&
@@ -2281,10 +2331,7 @@ subroutine writegriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,vargrid,no_inflat
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
endif
do k=1,nlevs
call mpi_scatterv(workvar3d(:,:,k),recvcounts2d,displs2d,mpi_real4,&
@@ -2315,10 +2362,7 @@ subroutine writegriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,vargrid,no_inflat
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
endif
do k=1,nlevs
call mpi_scatterv(workvar3d(:,:,k),recvcounts2d,displs2d,mpi_real4,&
@@ -2349,10 +2393,7 @@ subroutine writegriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,vargrid,no_inflat
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
endif
do k=1,nlevs
call mpi_scatterv(workvar3d(:,:,k),recvcounts2d,displs2d,mpi_real4,&
@@ -2382,10 +2423,7 @@ subroutine writegriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,vargrid,no_inflat
enddo
enddo
workvar3d=workvar3d+workinc3d
- if ( l_use_enkf_directZDA .and. cliptracers ) then ! set cliptracers to remove negative hydrometers
- clip = tiny(workvar3d(1,1,1))
- where (workvar3d < clip) workvar3d = clip
- end if
+ if ( cliptracers ) where (workvar3d < clip) workvar3d = clip
endif
do k=1,nlevs
call mpi_scatterv(workvar3d(:,:,k),recvcounts2d,displs2d,mpi_real4,&
@@ -2478,19 +2516,23 @@ subroutine writegriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,vargrid,no_inflat
! Return calculated values
return
end subroutine writegriddata_pnc
-subroutine type_bound_setupfile(this,fileid1,fv3fn1,fileid2,fv3fn2)
+subroutine type_bound_setupfile(this,fileid1,fv3fn1,fileid2,fv3fn2,fileid3,fv3fn3)
implicit none
class (type_fv3lamfile) :: this
integer(i_kind) fileid1
- integer(i_kind), optional :: fileid2
+ integer(i_kind), optional :: fileid2,fileid3
character(len=*)::fv3fn1
- character(len=*),optional ::fv3fn2
+ character(len=*),optional ::fv3fn2,fv3fn3
if (present (fileid2)) then
this%l_filecombined=.false.
this%fv3lamfilename(1)=trim(fv3fn1)
this%fv3lamfilename(2)=trim(fv3fn2)
this%fv3lam_fileid(1)=fileid1
this%fv3lam_fileid(2)=fileid2
+ if (present (fileid3)) then
+ this%fv3lamfilename(3)=trim(fv3fn3)
+ this%fv3lam_fileid(3)=fileid3
+ endif
else
this%l_filecombined=.true.
this%fv3lamfilename(1)=fv3fn1
@@ -2509,6 +2551,9 @@ subroutine type_bound_getidfn(this,vnamloc,fileid,fv3fn)
else if(ifindstrloc(vartracers,vnamloc)> 0) then
fv3fn=trim(this%fv3lamfilename(2))
fileid=this%fv3lam_fileid(2)
+ else if(ifindstrloc(varphysics,vnamloc)> 0) then
+ fv3fn=trim(this%fv3lamfilename(3))
+ fileid=this%fv3lam_fileid(3)
else
write(6,*)"the varname ",trim(vnamloc)," is not recognized in the ype_bound_getidfn, stop"
call stop2(23)
diff --git a/src/enkf/gridio_gfs.f90 b/src/enkf/gridio_gfs.f90
index fe5199e395..35a0c3fbe4 100644
--- a/src/enkf/gridio_gfs.f90
+++ b/src/enkf/gridio_gfs.f90
@@ -35,6 +35,7 @@ module gridio
! a required input for EFSO calculations
! 2019-03-13 Add precipitation components
! 2019-07-10 Add convective clouds
+! 2022-07-21 Draper: added read/write for sfc file for nc io (writeincrements, and readgridata)
!
! attributes:
! language: f95
@@ -88,24 +89,33 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
real(r_kind), dimension(ndimspec) :: vrtspec,divspec
real(r_kind), allocatable, dimension(:) :: psg,pstend,ak,bk
real(r_single),allocatable,dimension(:,:,:) :: ug3d,vg3d
- type(Dataset) :: dset
+ type(Dataset) :: dset, dset_sfc
type(Dimension) :: londim,latdim,levdim
integer(i_kind) :: u_ind, v_ind, tv_ind, q_ind, oz_ind, cw_ind
integer(i_kind) :: qr_ind, qs_ind, qg_ind
integer(i_kind) :: tsen_ind, ql_ind, qi_ind, prse_ind
integer(i_kind) :: ps_ind, pst_ind, sst_ind
+ ! surface
+ integer(i_kind) :: tmp2m_ind, spfh2m_ind, soilt1_ind, soilt2_ind, soilt3_ind
+ integer(i_kind) :: soilt4_ind,slc1_ind, slc2_ind, slc3_ind, slc4_ind
integer(i_kind) :: k,iret,nb,i,imem,idvc,nlonsin,nlatsin,nlevsin,ne,nanal
+ ! surface
+ integer(i_kind) :: nlonsin_sfc,nlatsin_sfc
+
logical ice
logical use_full_hydro
integer(i_kind), allocatable, dimension(:) :: mem_pe, lev_pe1, lev_pe2, iocomms
- integer(i_kind) :: iope, ionumproc, iolevs, krev
+ integer(i_kind) :: iope, ionumproc, iolevs, krev, ierr
integer(i_kind) :: ncstart(3), nccount(3)
! mpi gatherv things
integer(i_kind), allocatable, dimension(:) :: recvcounts, displs
real(r_single), dimension(nlons,nlats,nlevs) :: ug3d_0, vg3d_0
+ logical :: read_sfc_file, read_atm_file
+
+ call set_ncio_file_flags(vars3d, n3d, vars2d, n2d, read_sfc_file, read_atm_file)
! figure out what member to read and do MPI sub-communicator things
allocate(mem_pe(0:numproc-1))
@@ -142,6 +152,7 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
displs(i+1) = ((lev_pe1(i)-1)*nlons*nlats)
end do
+ if (read_atm_file) then
! loop through times and do the read
ne = 1
@@ -149,7 +160,6 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
write(charnanal,'(a3, i3.3)') 'mem', nanal
filename = trim(adjustl(datapath))//trim(adjustl(fileprefixes(nb)))//trim(charnanal)
- sfcfilename = trim(adjustl(datapath))//trim(adjustl(filesfcprefixes(nb)))//trim(charnanal)
if (use_gfs_ncio) then
dset = open_dataset(filename, paropen=.true., mpicomm=iocomms(mem_pe(nproc)))
londim = get_dim(dset,'grid_xt'); nlonsin = londim%len
@@ -157,7 +167,7 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
levdim = get_dim(dset,'pfull'); nlevsin = levdim%len
idvc=2
else
- print *, 'parallel read only supported for netCDF, stopping with error'
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** parallel read only supported for netCDF' , ' PROGRAM STOPS'
call stop2(23)
end if
ice = .false. ! calculate qsat w/resp to ice?
@@ -185,6 +195,9 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
sst_ind = getindex(vars2d, 'sst')
use_full_hydro = ( ql_ind > 0 .and. qi_ind > 0 .and. &
qr_ind > 0 .and. qs_ind > 0 .and. qg_ind > 0 )
+ ! Currently, we do not let precipiation to affect the enkf analysis
+ ! The following line will be removed after testing
+ use_full_hydro = .false.
if (.not. isinitialized) call init_spec_vars(nlons,nlats,ntrunc,4)
@@ -195,7 +208,7 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
call read_vardata(dset, 'pressfc', values_2d,errcode=iret)
if (iret /= 0) then
- print *,'error reading ps'
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading ps, iret= ',iret,' PROGRAM STOPS'
call stop2(31)
endif
psg = 0.01_r_kind*reshape(values_2d,(/nlons*nlats/))
@@ -215,12 +228,12 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
call read_vardata(dset, 'ugrd', ug3d, ncstart=ncstart, nccount=nccount, errcode=iret)
if (iret /= 0) then
- print *,'error reading ugrd'
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading ugrd, iret= ',iret,' PROGRAM STOPS'
call stop2(22)
endif
call read_vardata(dset, 'vgrd', vg3d, ncstart=ncstart, nccount=nccount, errcode=iret)
if (iret /= 0) then
- print *,'error reading vgrd'
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading vgrd, iret= ',iret,' PROGRAM STOPS'
call stop2(23)
endif
call mpi_gatherv(ug3d, recvcounts(iope+1), mpi_real4, ug3d_0, recvcounts, displs,&
@@ -247,12 +260,12 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
end if
call read_vardata(dset,'tmp', ug3d, ncstart=ncstart, nccount=nccount, errcode=iret)
if (iret /= 0) then
- print *,'error reading tmp'
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading tmp, iret= ',iret,' PROGRAM STOPS'
call stop2(24)
endif
call read_vardata(dset,'spfh', vg3d, ncstart=ncstart, nccount=nccount, errcode=iret)
if (iret /= 0) then
- print *,'error reading spfh'
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading spfh, iret= ',iret,' PROGRAM STOPS'
call stop2(25)
endif
call mpi_gatherv(ug3d, recvcounts(iope+1), mpi_real4, ug3d_0, recvcounts, displs,&
@@ -276,7 +289,7 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
if (oz_ind > 0) then
call read_vardata(dset, 'o3mr', ug3d, ncstart=ncstart, nccount=nccount, errcode=iret)
if (iret /= 0) then
- print *,'error reading o3mr'
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading o3mr, iret= ',iret,' PROGRAM STOPS'
call stop2(26)
endif
if (cliptracers) where (ug3d < clip) ug3d = clip
@@ -290,31 +303,122 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
end do
end if
endif
- if (cw_ind > 0 .or. ql_ind > 0 .or. qi_ind > 0) then
- call read_vardata(dset, 'clwmr', ug3d, ncstart=ncstart, nccount=nccount, errcode=iret)
- if (iret /= 0) then
- print *,'error reading clwmr'
- call stop2(27)
+ ! Read in hydrometeor fields based on control/state variables listed in anavinfo table
+ if (use_full_hydro) then
+ if(ql_ind > 0) then
+ call read_vardata(dset, 'clwmr', ug3d, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if (iret /= 0) then
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading clwmr, iret= ',iret,' PROGRAM STOPS'
+ call stop2(26)
+ endif
+ if (cliptracers) where (ug3d < clip) ug3d = clip
+ call mpi_gatherv(ug3d, recvcounts(iope+1), mpi_real4, ug3d_0, recvcounts, displs,&
+ mpi_real4, 0, iocomms(mem_pe(nproc)),iret)
+ if (iope==0) then
+ do k=1,nlevs
+ krev = nlevs-k+1
+ ug = reshape(ug3d_0(:,:,krev),(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(ql_ind-1)+k,nb,ne))
+ end do
+ end if
endif
- if (imp_physics == 11) then
- call read_vardata(dset, 'icmr', vg3d, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if(qi_ind > 0) then
+ call read_vardata(dset, 'icmr', ug3d, ncstart=ncstart, nccount=nccount, errcode=iret)
if (iret /= 0) then
- print *,'error reading icmr'
- call stop2(28)
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading icmr, iret= ',iret,' PROGRAM STOPS'
+ call stop2(26)
endif
- ug3d = ug3d + vg3d
+ if (cliptracers) where (ug3d < clip) ug3d = clip
+ call mpi_gatherv(ug3d, recvcounts(iope+1), mpi_real4, ug3d_0, recvcounts, displs,&
+ mpi_real4, 0, iocomms(mem_pe(nproc)),iret)
+ if (iope==0) then
+ do k=1,nlevs
+ krev = nlevs-k+1
+ ug = reshape(ug3d_0(:,:,krev),(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(qi_ind-1)+k,nb,ne))
+ end do
+ end if
+ endif
+ if(qr_ind > 0) then
+ call read_vardata(dset, 'rwmr', ug3d, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if (iret /= 0) then
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading rwmr, iret= ',iret,' PROGRAM STOPS'
+ call stop2(26)
+ endif
+ if (cliptracers) where (ug3d < clip) ug3d = clip
+ call mpi_gatherv(ug3d, recvcounts(iope+1), mpi_real4, ug3d_0, recvcounts, displs,&
+ mpi_real4, 0, iocomms(mem_pe(nproc)),iret)
+ if (iope==0) then
+ do k=1,nlevs
+ krev = nlevs-k+1
+ ug = reshape(ug3d_0(:,:,krev),(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(qr_ind-1)+k,nb,ne))
+ end do
+ end if
+ endif
+ if(qs_ind > 0) then
+ call read_vardata(dset, 'snmr', ug3d, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if (iret /= 0) then
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading snmr, iret= ',iret,' PROGRAM STOPS'
+ call stop2(26)
+ endif
+ if (cliptracers) where (ug3d < clip) ug3d = clip
+ call mpi_gatherv(ug3d, recvcounts(iope+1), mpi_real4, ug3d_0, recvcounts, displs,&
+ mpi_real4, 0, iocomms(mem_pe(nproc)),iret)
+ if (iope==0) then
+ do k=1,nlevs
+ krev = nlevs-k+1
+ ug = reshape(ug3d_0(:,:,krev),(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(qs_ind-1)+k,nb,ne))
+ end do
+ end if
+ endif
+ if(qg_ind > 0) then
+ call read_vardata(dset, 'grle', ug3d, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if (iret /= 0) then
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading grle, iret= ',iret,' PROGRAM STOPS'
+ call stop2(26)
+ endif
+ if (cliptracers) where (ug3d < clip) ug3d = clip
+ call mpi_gatherv(ug3d, recvcounts(iope+1), mpi_real4, ug3d_0, recvcounts, displs,&
+ mpi_real4, 0, iocomms(mem_pe(nproc)),iret)
+ if (iope==0) then
+ do k=1,nlevs
+ krev = nlevs-k+1
+ ug = reshape(ug3d_0(:,:,krev),(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(qg_ind-1)+k,nb,ne))
+ end do
+ end if
+ endif
+ else
+ ! Handle non-precipiting hydrometeors
+ ! if control or state variable is cw, make sure combine background ql and qi to cw
+ if (cw_ind > 0 .or. ql_ind > 0 .or. qi_ind > 0) then
+ call read_vardata(dset, 'clwmr', ug3d, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if (iret /= 0) then
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading clwmr, iret= ',iret,' PROGRAM STOPS'
+ call stop2(27)
+ endif
+ if (imp_physics == 11) then
+ call read_vardata(dset, 'icmr', vg3d, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if (iret /= 0) then
+ write(6,*)'READGRIDDATA_PNC: ***FATAL ERROR*** reading icmr, iret= ',iret,' PROGRAM STOPS'
+ call stop2(28)
+ endif
+ ug3d = ug3d + vg3d
+ endif
+ if (cliptracers) where (ug3d < clip) ug3d = clip
+ call mpi_gatherv(ug3d, recvcounts(iope+1), mpi_real4, ug3d_0, recvcounts, displs,&
+ mpi_real4, 0, iocomms(mem_pe(nproc)),iret)
+ if (iope==0) then
+ do k=1,nlevs
+ krev = nlevs-k+1
+ ug = reshape(ug3d_0(:,:,krev),(/nlons*nlats/))
+ call copytogrdin(ug,cw(:,k))
+ if (cw_ind > 0) grdin(:,levels(cw_ind-1)+k,nb,ne) = cw(:,k)
+ end do
+ end if
endif
- if (cliptracers) where (ug3d < clip) ug3d = clip
- call mpi_gatherv(ug3d, recvcounts(iope+1), mpi_real4, ug3d_0, recvcounts, displs,&
- mpi_real4, 0, iocomms(mem_pe(nproc)),iret)
- if (iope==0) then
- do k=1,nlevs
- krev = nlevs-k+1
- ug = reshape(ug3d_0(:,:,krev),(/nlons*nlats/))
- call copytogrdin(ug,cw(:,k))
- if (cw_ind > 0) grdin(:,levels(cw_ind-1)+k,nb,ne) = cw(:,k)
- end do
- end if
endif
deallocate(ug3d,vg3d)
@@ -355,22 +459,25 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
end if
! cloud derivatives
+ ! Currently, we do not let precipiation to affect the enkf analysis
+ ! The following line will be removed after testing
+ use_full_hydro = .true.
if (.not. use_full_hydro .and. iope==0) then
- if (ql_ind > 0 .or. qi_ind > 0) then
- do k=1,nlevs
- do i = 1, npts
- qi_coef = -r0_05*(tv(i,k)/(one+fv*q(i,k))-t0c)
- qi_coef = max(zero,qi_coef)
- qi_coef = min(one,qi_coef) ! 0<=qi_coef<=1
- if (ql_ind > 0) then
- grdin(i,levels(ql_ind-1)+k,nb,ne) = cw(i,k)*(one-qi_coef)
- endif
- if (qi_ind > 0) then
- grdin(i,levels(qi_ind-1)+k,nb,ne) = cw(i,k)*qi_coef
- endif
+ if (ql_ind > 0 .or. qi_ind > 0) then
+ do k=1,nlevs
+ do i = 1, npts
+ qi_coef = -r0_05*(tv(i,k)/(one+fv*q(i,k))-t0c)
+ qi_coef = max(zero,qi_coef)
+ qi_coef = min(one,qi_coef) ! 0<=qi_coef<=1
+ if (ql_ind > 0) then
+ grdin(i,levels(ql_ind-1)+k,nb,ne) = cw(i,k)*(one-qi_coef)
+ endif
+ if (qi_ind > 0) then
+ grdin(i,levels(qi_ind-1)+k,nb,ne) = cw(i,k)*qi_coef
+ endif
+ enddo
enddo
- enddo
- endif
+ endif
endif
if (sst_ind > 0 .and. iope==0) then
@@ -389,6 +496,141 @@ subroutine readgriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,ntimes, &
end do backgroundloop ! loop over backgrounds to read in
+ end if !read_atm_file
+
+ if (read_sfc_file) then
+ ! loop through times and do the read
+ ne = 1
+ sfcbackgroundloop: do nb=1,ntimes
+
+ write(charnanal,'(a3, i3.3)') 'mem', nanal
+ sfcfilename = trim(adjustl(datapath))//trim(adjustl(filesfcprefixes(nb)))//trim(charnanal)
+ if (use_gfs_ncio) then
+ dset_sfc = open_dataset(sfcfilename, paropen=.true., mpicomm=iocomms(mem_pe(nproc)))
+ else
+ write(6,*)'READGRIDDATA_PNC sfc: ***FATAL ERROR*** parallel read only supported for netCDF' , ' PROGRAM STOPS'
+ call mpi_barrier(mpi_comm_world,ierr)
+ call mpi_finalize(ierr)
+ end if
+ if ( reducedgrid ) then
+ write(6,*) "READGRIDDATA_PNC sfc: reducedgrid=T interpolation not valid for writing sfc files"
+ call mpi_barrier(mpi_comm_world,ierr)
+ call mpi_finalize(ierr)
+ endif
+
+ ! land sfc DA variables
+ tmp2m_ind = getindex(vars2d, 't2m')
+ spfh2m_ind = getindex(vars2d, 'q2m')
+ soilt1_ind = getindex(vars2d, 'st1')
+ slc1_ind = getindex(vars2d, 'sl1')
+ soilt2_ind = getindex(vars2d, 'st2')
+ slc2_ind = getindex(vars2d, 'sl2')
+ soilt3_ind = getindex(vars2d, 'st3')
+ slc3_ind = getindex(vars2d, 'sl3')
+ soilt4_ind = getindex(vars2d, 'st4')
+ slc4_ind = getindex(vars2d, 'sl4')
+
+ ! read in sfc vars, if requested
+ if (tmp2m_ind > 0) then
+ call read_vardata(dset_sfc, 'tmp2m', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'READGRIDDATA_PNC: error reading tmp2m'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ if (iope==0) call copytogrdin(ug,grdin(:,levels(n3d) + tmp2m_ind,nb,ne))
+ endif
+ if (spfh2m_ind > 0) then
+ call read_vardata(dset_sfc, 'spfh2m', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'READGRIDDATA_PNC: error reading spfh2m'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ if (iope==0) call copytogrdin(ug,grdin(:,levels(n3d) + spfh2m_ind,nb,ne))
+ endif
+ if (soilt1_ind > 0) then
+ call read_vardata(dset_sfc, 'soilt1', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'READGRIDDATA_PNC: error reading soilt1'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ if (iope==0) call copytogrdin(ug,grdin(:,levels(n3d) + soilt1_ind,nb,ne))
+ endif
+ if (soilt2_ind > 0) then
+ call read_vardata(dset_sfc, 'soilt2', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'READGRIDDATA_PNC: error reading soilt2'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ if (iope==0) call copytogrdin(ug,grdin(:,levels(n3d) + soilt2_ind,nb,ne))
+ endif
+ if (soilt3_ind > 0) then
+ call read_vardata(dset_sfc, 'soilt3', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'READGRIDDATA_PNC: error reading soilt3'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ if (iope==0) call copytogrdin(ug,grdin(:,levels(n3d) + soilt3_ind,nb,ne))
+ endif
+ if (soilt4_ind > 0) then
+ call read_vardata(dset_sfc, 'soilt4', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'READGRIDDATA_PNC: error reading soilt2'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ if (iope==0) call copytogrdin(ug,grdin(:,levels(n3d) + soilt4_ind,nb,ne))
+ endif
+ if (slc1_ind > 0) then
+ call read_vardata(dset_sfc, 'soill1', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'READGRIDDATA_PNC: error reading soill1'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ if (iope==0) call copytogrdin(ug,grdin(:,levels(n3d) + slc1_ind,nb,ne))
+ endif
+ if (slc2_ind > 0) then
+ call read_vardata(dset_sfc, 'soill2', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'READGRIDDATA_PNC: error reading soill2'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ if (iope==0) call copytogrdin(ug,grdin(:,levels(n3d) + slc2_ind,nb,ne))
+ endif
+ if (slc3_ind > 0) then
+ call read_vardata(dset_sfc, 'soill3', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'READGRIDDATA_PNC: error reading soill3'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ if (iope==0) call copytogrdin(ug,grdin(:,levels(n3d) + slc3_ind,nb,ne))
+ endif
+ if (slc4_ind > 0) then
+ call read_vardata(dset_sfc, 'soill4', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'READGRIDDATA_PNC: error reading soill4'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ if (iope==0) call copytogrdin(ug,grdin(:,levels(n3d) + slc4_ind,nb,ne))
+ endif
+
+ ! bring all the subdomains back to the main PE
+ call mpi_barrier(iocomms(mem_pe(nproc)), iret)
+ if (allocated(values_2d)) deallocate(values_2d)
+ call close_dataset(dset_sfc)
+ call mpi_barrier(iocomms(mem_pe(nproc)), iret)
+
+ end do sfcbackgroundloop ! loop over backgrounds to read in
+ end if !if (read_sfc_file)
+
! remove the sub communicators
call mpi_barrier(iocomms(mem_pe(nproc)), iret)
call mpi_comm_free(iocomms(mem_pe(nproc)), iret)
@@ -457,7 +699,7 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
type(sigio_head) :: sighead
type(sigio_data) :: sigdata
type(nemsio_gfile) :: gfile
- type(Dataset) :: dset
+ type(Dataset) :: dset, dset_sfc
type(Dimension) :: londim,latdim,levdim
type(nemsio_gfile) :: gfilesfc
@@ -465,14 +707,20 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
integer(i_kind) :: qr_ind, qs_ind, qg_ind
integer(i_kind) :: tsen_ind, ql_ind, qi_ind, prse_ind
integer(i_kind) :: ps_ind, pst_ind, sst_ind
+ integer(i_kind) :: tmp2m_ind, spfh2m_ind, soilt1_ind, soilt2_ind, soilt3_ind
+ integer(i_kind) :: soilt4_ind,slc1_ind, slc2_ind, slc3_ind, slc4_ind
integer(i_kind) :: k,iunitsig,iret,nb,i,idvc,nlonsin,nlatsin,nlevsin,ne,nanal
integer(i_kind) :: nlonsin_sfc,nlatsin_sfc
logical ice
logical use_full_hydro
+ logical read_sfc_file, read_atm_file
use_full_hydro = .false.
+ ! determine which files will be read in
+ call set_ncio_file_flags(vars3d, n3d, vars2d, n2d, read_sfc_file, read_atm_file)
+
ne = 0
ensmemloop: do nanal=nanal1,nanal2
ne = ne + 1
@@ -565,6 +813,7 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
! print *, 'ql: ', ql_ind, ', prse: ', prse_ind
! print *, 'ps: ', ps_ind, ', pst: ', pst_ind, ', sst: ', sst_ind
! endif
+ if (read_atm_file) then
if (.not. isinitialized) call init_spec_vars(nlons,nlats,ntrunc,4)
@@ -634,7 +883,7 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
pressi(:,k) = 0.01_r_kind*ak(nlevs-k+2)+bk(nlevs-k+2)*psg
if (nanal .eq. 1) print *,'netcdf, min/max pressi',k,minval(pressi(:,k)),maxval(pressi(:,k))
enddo
- deallocate(ak,bk,values_2d)
+ deallocate(ak,bk)
else
vrtspec = sigdata%ps
call sptez_s(vrtspec,psg,1)
@@ -812,6 +1061,7 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
endif ! use_full_hydro
enddo
else if (use_gfs_ncio) then
+ clip=tiny_r_kind
call read_vardata(dset, 'ugrd', ug3d,errcode=iret)
if (iret /= 0) then
print *,'error reading ugrd'
@@ -1003,10 +1253,134 @@ subroutine readgriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,ntimes,
deallocate(pressi,pslg)
deallocate(psg)
if (pst_ind > 0) deallocate(vmassdiv,pstend)
+ endif ! read_atm_file
+
if (use_gfs_nemsio) call nemsio_close(gfile,iret=iret)
if (use_gfs_ncio) call close_dataset(dset)
if (use_gfs_nemsio) call nemsio_close(gfilesfc,iret=iret)
+ if ( read_sfc_file ) then
+
+ if ( .not. use_gfs_ncio ) then
+ write(6,*) 'griddio/griddata for sfc update vars only coded for nc io'
+ call stop2(23)
+ endif
+ if ( reducedgrid ) then
+ write(6,*) "reducedgrid=T interpolation not valid for writing sfc files"
+ call stop2(22)
+ endif
+
+ ! land sfc DA variables
+ tmp2m_ind = getindex(vars2d, 't2m')
+ spfh2m_ind = getindex(vars2d, 'q2m')
+ soilt1_ind = getindex(vars2d, 'st1')
+ slc1_ind = getindex(vars2d, 'sl1')
+ soilt2_ind = getindex(vars2d, 'st2')
+ slc2_ind = getindex(vars2d, 'sl2')
+ soilt3_ind = getindex(vars2d, 'st3')
+ slc3_ind = getindex(vars2d, 'sl3')
+ soilt4_ind = getindex(vars2d, 'st4')
+ slc4_ind = getindex(vars2d, 'sl4')
+
+ dset_sfc = open_dataset(filenamesfc)
+ ! read in sfc vars, if requested
+ if (tmp2m_ind > 0) then
+ call read_vardata(dset_sfc, 'tmp2m', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'error reading tmp2m'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(n3d) + tmp2m_ind,nb,ne))
+ endif
+ if (spfh2m_ind > 0) then
+ call read_vardata(dset_sfc, 'spfh2m', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'error reading spfh2m'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(n3d) + spfh2m_ind,nb,ne))
+ endif
+ if (soilt1_ind > 0) then
+ call read_vardata(dset_sfc, 'soilt1', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'error reading soilt1'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(n3d) + soilt1_ind,nb,ne))
+ endif
+ if (soilt2_ind > 0) then
+ call read_vardata(dset_sfc, 'soilt2', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'error reading soilt2'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(n3d) + soilt2_ind,nb,ne))
+ endif
+ if (soilt3_ind > 0) then
+ call read_vardata(dset_sfc, 'soilt3', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'error reading soilt3'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(n3d) + soilt3_ind,nb,ne))
+ endif
+ if (soilt4_ind > 0) then
+ call read_vardata(dset_sfc, 'soilt4', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'error reading soilt2'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(n3d) + soilt4_ind,nb,ne))
+ endif
+ if (slc1_ind > 0) then
+ call read_vardata(dset_sfc, 'soill1', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'error reading soill1'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(n3d) + slc1_ind,nb,ne))
+ endif
+ if (slc2_ind > 0) then
+ call read_vardata(dset_sfc, 'soill2', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'error reading soill2'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(n3d) + slc2_ind,nb,ne))
+ endif
+ if (slc3_ind > 0) then
+ call read_vardata(dset_sfc, 'soill3', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'error reading soill3'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(n3d) + slc3_ind,nb,ne))
+ endif
+ if (slc4_ind > 0) then
+ call read_vardata(dset_sfc, 'soill4', values_2d, errcode=iret)
+ if (iret /= 0) then
+ print *,'error reading soill4'
+ call stop2(22)
+ endif
+ ug = reshape(values_2d,(/nlons*nlats/))
+ call copytogrdin(ug,grdin(:,levels(n3d) + slc4_ind,nb,ne))
+ endif
+
+ call close_dataset(dset_sfc)
+
+ endif ! sfc read
+
+ if ( allocated(values_2d) ) deallocate(values_2d)
+
end do backgroundloop ! loop over backgrounds to read in
end do ensmemloop ! loop over ens members to read in
@@ -1083,6 +1457,20 @@ subroutine writegriddata_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate_
integer(i_kind) :: ncstart(4), nccount(4)
logical :: nocompress
+ logical :: write_sfc_file, write_atm_file
+ character(len=max_varname_length), dimension(n3d) :: no_vars3d
+ character(len=max_varname_length), dimension(n2d) :: no_vars2d
+
+ call set_ncio_file_flags(vars3d, n3d, vars2d, n2d, write_sfc_file, write_atm_file)
+
+ if (write_sfc_file ) then
+ ! adding the sfc increments requires adjusting several other variables.
+ ! This is done is a separate program.
+ if (nproc == 0) write(6,*) 'gridio/writegriddata_pnc: not coded to write sfc analysis, will write increment for sfc fields'
+ no_vars3d=''
+ call writeincrement_pnc(no_vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate_flag)
+ endif
+
nocompress = .true.
if (nccompress) nocompress = .false.
@@ -1884,6 +2272,7 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,grdin,n
character(nemsio_charkind) :: field
character(len=nf90_max_name) :: time_units
logical :: hasfield
+ character(len=max_varname_length), dimension(n3d) :: no_vars3d
real(r_kind) kap,kapr,kap1,clip
real(r_single) compress_err
@@ -1901,6 +2290,17 @@ subroutine writegriddata(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,grdin,n
integer k,krev,nt,ierr,iunitsig,nb,i,ne,nanal
logical :: nocompress
+ logical :: write_sfc_file, write_atm_file
+
+ call set_ncio_file_flags(vars3d, n3d, vars2d, n2d, write_sfc_file, write_atm_file)
+
+ if (write_sfc_file ) then
+ ! adding the sfc increments requires adjusting several other variables. This is done is a separate
+ ! program.
+ if (nproc == 0) write(6,*)'gridio/writegriddata: not coded to write sfc analysis, will write increment for sfc fields'
+ no_vars3d=''
+ call writeincrement(nanal1,nanal2,no_vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate_flag)
+ endif
nocompress = .true.
if (nccompress) nocompress = .false.
@@ -3305,7 +3705,7 @@ end subroutine writegriddata
subroutine writeincrement(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate_flag)
use netcdf
use params, only: nbackgrounds,incfileprefixes,fgfileprefixes,reducedgrid,&
- datestring,nhr_anal,write_ensmean
+ datestring,nhr_anal,write_ensmean, fgsfcfileprefixes,incsfcfileprefixes
use constants, only: grav
use mpi
use module_ncio, only: Dataset, Variable, Dimension, open_dataset,&
@@ -3337,11 +3737,16 @@ subroutine writeincrement(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,grdin,
integer :: ql_ind, qi_ind, qr_ind, qs_ind, qg_ind
! netcdf things
- integer(i_kind) :: dimids3(3), ncstart(3), nccount(3)
+ integer(i_kind) :: dimids3(3), ncstart(3), nccount(3), dimids2(2)
integer(i_kind) :: ncid_out, lon_dimid, lat_dimid, lev_dimid, ilev_dimid
integer(i_kind) :: lonvarid, latvarid, levvarid, pfullvarid, ilevvarid, &
hyaivarid, hybivarid, uvarid, vvarid, delpvarid, delzvarid, &
- tvarid, sphumvarid, liqwatvarid, o3varid, icvarid
+ tvarid, sphumvarid, liqwatvarid, o3varid, icvarid, &
+ tmp2mvarid, spfh2mvarid, soilt1varid, soilt2varid, &
+ soilt3varid, soilt4varid, slc1varid, slc2varid, &
+ slc3varid, slc4varid, maskvarid
+ integer(i_kind) :: tmp2m_ind, spfh2m_ind, soilt1_ind, soilt2_ind, soilt3_ind, &
+ soilt4_ind,slc1_ind, slc2_ind, slc3_ind, slc4_ind
integer(i_kind) :: iadateout
! fixed fields such as lat, lon, levs
@@ -3353,9 +3758,16 @@ subroutine writeincrement(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,grdin,
! increment
real(r_kind), dimension(nlons*nlats) :: psinc, inc, ug, vg, work
real(r_single), allocatable, dimension(:,:,:) :: inc3d, inc3d2, inc3dout
+ real(r_single), allocatable, dimension(:,:) :: inc2d, inc2dout
real(r_single), allocatable, dimension(:,:,:) :: tv, tvanl, tmp, tmpanl, q, qanl
real(r_kind), allocatable, dimension(:,:) :: values_2d
real(r_kind), allocatable, dimension(:) :: psges, delzb, values_1d
+ ! soil / snow mask (not fixed)
+ integer(i_kind), dimension(nlons,nlats) :: mask
+ logical :: write_sfc_file, write_atm_file
+ real(r_double) :: t1,t2
+
+ call set_ncio_file_flags(vars3d, n3d, vars2d, n2d, write_sfc_file, write_atm_file)
use_full_hydro = .false.
clip = tiny_r_kind
@@ -3364,6 +3776,8 @@ subroutine writeincrement(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,grdin,
ncstart = (/1, 1, 1/)
nccount = (/nlons, nlats, nlevs/)
+ if ( write_atm_file) then
+ if (nproc == 0) t1 = mpi_wtime()
ne = 0
ensmemloop: do nanal=nanal1,nanal2
ne = ne + 1
@@ -3677,14 +4091,277 @@ subroutine writeincrement(nanal1,nanal2,vars3d,vars2d,n3d,n2d,levels,ndim,grdin,
call nccheck_incr(nf90_put_var(ncid_out, icvarid, sngl(inc3dout), &
start = ncstart, count = nccount))
+ call close_dataset(dsfg,errcode=iret)
+ if (iret/=0) then
+ write(6,*)'gridio/writeincrement gfs model: problem closing netcdf fg dataset, iret=',iret
+ call stop2(23)
+ endif
! deallocate things
deallocate(inc3d,inc3d2,inc3dout)
deallocate(tmp,tv,q,tmpanl,tvanl,qanl)
- deallocate(delzb,psges)
+ if (allocated(delzb)) deallocate(delzb)
+ if (allocated(psges)) deallocate(psges)
end do backgroundloop ! loop over backgrounds to read in
end do ensmemloop ! loop over ens members to read in
+ if (nproc == 0) then
+ t2 = mpi_wtime()
+ print *,'time in writeincrement atm_file on root',t2-t1,'secs'
+ endif
+ endif ! write_atm_file
+
+ if (write_sfc_file) then
+
+ if (nproc == 0) t1 = mpi_wtime()
+ ne = 0
+ sfcensmemloop: do nanal=nanal1,nanal2
+ ne = ne + 1
+ write(charnanal,'(i3.3)') nanal
+ sfcbackgroundloop: do nb=1,nbackgrounds
+
+ if (nanal == 0 .and. write_ensmean) then
+ filenamein = trim(adjustl(datapath))//trim(adjustl(fgsfcfileprefixes(nb)))//"ensmean"
+ filenameout = trim(adjustl(datapath))//trim(adjustl(incsfcfileprefixes(nb)))//"ensmean"
+ else
+ if(no_inflate_flag) then
+ filenameout = trim(adjustl(datapath))//trim(adjustl(incsfcfileprefixes(nb)))//"nimem"//charnanal
+ else
+ filenameout = trim(adjustl(datapath))//trim(adjustl(incsfcfileprefixes(nb)))//"mem"//charnanal
+ end if
+ filenamein = trim(adjustl(datapath))//trim(adjustl(fgsfcfileprefixes(nb)))//"mem"//charnanal
+ endif
+
+ ! create the output netCDF increment file
+ call nccheck_incr(nf90_create(path=trim(filenameout), cmode=nf90_netcdf4, ncid=ncid_out))
+
+ ! create dimensions based on analysis resolution, not guess
+ call nccheck_incr(nf90_def_dim(ncid_out, "longitude", nlons, lon_dimid))
+ call nccheck_incr(nf90_def_dim(ncid_out, "latitude", nlats, lat_dimid))
+ dimids2 = (/ lon_dimid, lat_dimid /)
+ ! create variables
+ call nccheck_incr(nf90_def_var(ncid_out, "longitude", nf90_real, (/lon_dimid/), lonvarid))
+ call nccheck_incr(nf90_def_var(ncid_out, "latitude", nf90_real, (/lat_dimid/), latvarid))
+ call nccheck_incr(nf90_def_var(ncid_out, "tmp2m_inc", nf90_real, dimids2, tmp2mvarid))
+ call nccheck_incr(nf90_def_var(ncid_out, "spfh2m_inc", nf90_real, dimids2, spfh2mvarid))
+ call nccheck_incr(nf90_def_var(ncid_out, "soilt1_inc", nf90_real, dimids2, soilt1varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "soilt2_inc", nf90_real, dimids2, soilt2varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "soilt3_inc", nf90_real, dimids2, soilt3varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "soilt4_inc", nf90_real, dimids2, soilt4varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "slc1_inc", nf90_real, dimids2, slc1varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "slc2_inc", nf90_real, dimids2, slc2varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "slc3_inc", nf90_real, dimids2, slc3varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "slc4_inc", nf90_real, dimids2, slc4varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "soilsnow_mask", nf90_int, dimids2, maskvarid))
+ ! place global attributes to serial calc_increment output
+ call nccheck_incr(nf90_put_att(ncid_out, nf90_global, "source", "GSI EnKF"))
+ call nccheck_incr(nf90_put_att(ncid_out, nf90_global, "comment", &
+ "global landsfc anal increment from writeincrement"))
+ call nccheck_incr(nf90_put_att(ncid_out, nf90_global, "analysis_time", iadateout))
+ call nccheck_incr(nf90_put_att(ncid_out, nf90_global, "IAU_hour_from_guess", nhr_anal(nb)))
+ ! add units to lat/lon because that's what the calc_increment utility has
+ call nccheck_incr(nf90_put_att(ncid_out, lonvarid, "units", "degrees_east"))
+ call nccheck_incr(nf90_put_att(ncid_out, latvarid, "units", "degrees_north"))
+ ! end the netCDF file definition
+ call nccheck_incr(nf90_enddef(ncid_out))
+
+ tmp2m_ind = getindex(vars2d, 't2m') !< indices in the state or control var arrays
+ spfh2m_ind = getindex(vars2d, 'q2m')
+ soilt1_ind = getindex(vars2d, 'st1')
+ slc1_ind = getindex(vars2d, 'sl1')
+ soilt2_ind = getindex(vars2d, 'st2')
+ slc2_ind = getindex(vars2d, 'sl2')
+ soilt3_ind = getindex(vars2d, 'st3')
+ slc3_ind = getindex(vars2d, 'sl3')
+ soilt4_ind = getindex(vars2d, 'st4')
+ slc4_ind = getindex(vars2d, 'sl4')
+
+ dsfg = open_dataset(filenamein)
+
+ ! longitudes
+ call read_vardata(dsfg, 'grid_xt', values_1d, errcode=iret)
+ deglons(:) = values_1d
+ call nccheck_incr(nf90_put_var(ncid_out, lonvarid, deglons, &
+ start = (/1/), count = (/nlons/)))
+
+ call read_vardata(dsfg, 'grid_yt', values_1d, errcode=iret)
+ ! latitudes
+ do j=1,nlats
+ deglats(nlats-j+1) = values_1d(j)
+ end do
+
+ call nccheck_incr(nf90_put_var(ncid_out, latvarid, deglats, &
+ start = (/1/), count = (/nlats/)))
+
+ ! construct mask (1 - soil, 2 - snow, 0 - not snow)
+ ! note: same logic/threshold used in global_cycle to produce
+ ! mask on model grid.
+
+ call read_vardata(dsfg, 'soill1', values_2d, errcode=iret)
+
+ mask = 0
+ do j=1,nlats
+ do i = 1, nlons
+ if (values_2d(i,j) .LT. 1.0) then
+ mask(i,nlats-j+1) = 1
+ endif
+ enddo
+ end do
+
+ call read_vardata(dsfg, 'weasd', values_2d, errcode=iret)
+ do j=1,nlats
+ do i = 1, nlons
+ if (values_2d(i,j) .GT. 0.001) then
+ mask(i,nlats-j+1) = 2
+ endif
+ enddo
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, maskvarid, mask, &
+ start = ncstart(1:2), count = nccount(1:2)))
+
+ allocate(inc2d(nlons,nlats))
+ allocate(inc2dout(nlons,nlats))
+
+ ! tmp2m increment
+ inc(:) = zero
+ if (tmp2m_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d) + tmp2m_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, tmp2mvarid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! spfh2m increment
+ inc(:) = zero
+ if (spfh2m_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+spfh2m_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, spfh2mvarid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! soilt1 increment
+ inc(:) = zero
+ if (soilt1_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+soilt1_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ inc2dout=0.
+ do j=1,nlats
+ do i = 1, nlons
+ if (mask(i,nlats-j+1) .NE. 0) inc2dout(i,nlats-j+1) = inc2d(i,j)
+ enddo
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, soilt1varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! soilt2 increment
+ inc(:) = zero
+ if (soilt2_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+soilt2_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ inc2dout=0.
+ do j=1,nlats
+ do i = 1, nlons
+ if (mask(i,nlats-j+1) .NE. 0) inc2dout(i,nlats-j+1) = inc2d(i,j)
+ enddo
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, soilt2varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! soilt3 increment
+ inc(:) = zero
+ if (soilt3_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+soilt3_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ inc2dout=0.
+ do j=1,nlats
+ do i = 1, nlons
+ if (mask(i,nlats-j+1) .NE. 0) inc2dout(i,nlats-j+1) = inc2d(i,j)
+ enddo
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, soilt3varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! soilt4 increment
+ inc(:) = zero
+ if (soilt4_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+soilt4_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ inc2dout=0.
+ do j=1,nlats
+ do i = 1, nlons
+ if (mask(i,nlats-j+1) .NE. 0) inc2dout(i,nlats-j+1) = inc2d(i,j)
+ enddo
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, soilt4varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! slc1 increment
+ inc(:) = zero
+ if (slc1_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+slc1_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, slc1varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! slc2 increment
+ inc(:) = zero
+ if (slc2_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+slc2_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, slc2varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! slc3 increment
+ inc(:) = zero
+ if (slc3_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+slc3_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, slc3varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! slc4 increment
+ inc(:) = zero
+ if (slc4_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+slc4_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, slc4varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+
+ call close_dataset(dsfg,errcode=iret)
+ if (iret/=0) then
+ write(6,*)'gridio/writeincrement gfs model: problem closing netcdf sfc fg dataset, iret=',iret
+ call stop2(23)
+ endif
+ ! deallocate things
+ deallocate(inc2d,inc2dout)
+
+ end do sfcbackgroundloop ! loop over backgrounds to read in
+ end do sfcensmemloop ! loop over ens members to read in
+ if (nproc == 0) then
+ t2 = mpi_wtime()
+ print *,'time in writeincrement sfc_file on root',t2-t1,'secs'
+ endif
+
+ endif ! write_sfc_file
+
return
contains
@@ -3708,8 +4385,9 @@ end subroutine writeincrement
subroutine writeincrement_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate_flag)
use netcdf
use params, only: nbackgrounds,incfileprefixes,fgfileprefixes,reducedgrid,&
- datestring,nhr_anal
- use constants, only: grav
+ datestring,nhr_anal, &
+ incsfcfileprefixes,fgsfcfileprefixes
+ use constants, only: grav,qcmin
use mpi
use module_ncio, only: Dataset, Variable, Dimension, open_dataset,&
read_attribute, close_dataset, get_dim, read_vardata,&
@@ -3740,11 +4418,17 @@ subroutine writeincrement_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate
integer :: ql_ind, qi_ind, qr_ind, qs_ind, qg_ind
! netcdf things
- integer(i_kind) :: dimids3(3),nccount(3),ncstart(3)
+ integer(i_kind) :: dimids3(3),nccount(3),ncstart(3), dimids2(2)
integer(i_kind) :: ncid_out, lon_dimid, lat_dimid, lev_dimid, ilev_dimid
integer(i_kind) :: lonvarid, latvarid, levvarid, pfullvarid, ilevvarid, &
hyaivarid, hybivarid, uvarid, vvarid, delpvarid, delzvarid, &
- tvarid, sphumvarid, liqwatvarid, o3varid, icvarid
+ tvarid, sphumvarid, liqwatvarid, o3varid, icvarid, &
+ rwmrvarid, snmrvarid, grlevarid, &
+ tmp2mvarid, spfh2mvarid, soilt1varid, soilt2varid, &
+ soilt3varid, soilt4varid, slc1varid, slc2varid, &
+ slc3varid, slc4varid, maskvarid
+ integer(i_kind) :: tmp2m_ind, spfh2m_ind, soilt1_ind, soilt2_ind,soilt3_ind, &
+ soilt4_ind,slc1_ind, slc2_ind, slc3_ind, slc4_ind
integer(i_kind) :: iadateout
! fixed fields such as lat, lon, levs
@@ -3756,10 +4440,20 @@ subroutine writeincrement_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate
! increment
real(r_kind), dimension(nlons*nlats) :: psinc, inc, ug, vg, work
real(r_single), allocatable, dimension(:,:,:) :: inc3d, inc3d2, inc3dout
+ real(r_single), allocatable, dimension(:,:) :: inc2d, inc2dout
real(r_single), allocatable, dimension(:,:,:) :: tv, tvanl, tmp, tmpanl, q, qanl
+ real(r_single), allocatable, dimension(:,:,:) :: q2, qanl2
real(r_kind), allocatable, dimension(:,:) :: values_2d
real(r_kind), allocatable, dimension(:) :: psges, delzb, values_1d
+ ! soil / snow mask (not fixed)
+ integer(i_kind), dimension(nlons,nlats) :: mask
+
+ logical :: write_sfc_file, write_atm_file
+ real(r_double) :: t1,t2
+
+ call set_ncio_file_flags(vars3d, n3d, vars2d, n2d, write_sfc_file, write_atm_file)
+
use_full_hydro = .false.
clip = tiny_r_kind
read(datestring,*) iadateout
@@ -3798,6 +4492,9 @@ subroutine writeincrement_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate
call mpi_bcast(grdin(1,1,nb,1),npts*ndim, mpi_real4, 0, iocomms(mem_pe(nproc)), iret)
enddo
+ if (write_atm_file ) then
+
+ if (nproc == 0) t1 = mpi_wtime()
! loop through times and do the read
ne = 1
backgroundloop: do nb=1,nbackgrounds
@@ -3846,6 +4543,12 @@ subroutine writeincrement_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate
call nccheck_incr(nf90_var_par_access(ncid_out, o3varid, nf90_collective))
call nccheck_incr(nf90_def_var(ncid_out, "icmr_inc", nf90_real, dimids3, icvarid))
call nccheck_incr(nf90_var_par_access(ncid_out, icvarid, nf90_collective))
+ call nccheck_incr(nf90_def_var(ncid_out, "rwmr_inc", nf90_real, dimids3, rwmrvarid))
+ call nccheck_incr(nf90_var_par_access(ncid_out, rwmrvarid, nf90_collective))
+ call nccheck_incr(nf90_def_var(ncid_out, "snmr_inc", nf90_real, dimids3, snmrvarid))
+ call nccheck_incr(nf90_var_par_access(ncid_out, snmrvarid, nf90_collective))
+ call nccheck_incr(nf90_def_var(ncid_out, "grle_inc", nf90_real, dimids3, grlevarid))
+ call nccheck_incr(nf90_var_par_access(ncid_out, grlevarid, nf90_collective))
! place global attributes to parallel calc_increment output
call nccheck_incr(nf90_put_att(ncid_out, nf90_global, "source", "GSI EnKF"))
call nccheck_incr(nf90_put_att(ncid_out, nf90_global, "comment", &
@@ -3878,7 +4581,7 @@ subroutine writeincrement_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate
dsfg = open_dataset(filenamein, paropen=.true., mpicomm=iocomms(mem_pe(nproc)))
call read_attribute(dsfg, 'ak', values_1d,errcode=iret)
if (iret /= 0) then
- print *,'error reading ak'
+ write(6,*)'WRITEINCREMENT_PNC: ***FATAL ERROR*** reading ak, iret= ',iret,' PROGRAM STOPS'
call stop2(29)
endif
do k=1,nlevs+1
@@ -3887,7 +4590,7 @@ subroutine writeincrement_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate
enddo
call read_attribute(dsfg, 'bk', values_1d,errcode=iret)
if (iret /= 0) then
- print *,'error reading bk'
+ write(6,*)'WRITEINCREMENT_PNC: ***FATAL ERROR*** reading bk, iret= ',iret,' PROGRAM STOPS'
call stop2(29)
endif
do k=1,nlevs+1
@@ -3997,7 +4700,7 @@ subroutine writeincrement_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate
allocate(tvanl(nlons,nlats,nccount(3)),tmpanl(nlons,nlats,nccount(3)),qanl(nlons,nlats,nccount(3)))
call read_vardata(dsfg, 'spfh', q, ncstart=ncstart, nccount=nccount, errcode=iret)
if (iret /= 0) then
- print *,'error reading spfh'
+ write(6,*)'WRITEINCREMENT_PNC: ***FATAL ERROR*** reading spfh, iret= ',iret,' PROGRAM STOPS'
call stop2(29)
endif
do k=lev_pe1(iope), lev_pe2(iope)
@@ -4022,7 +4725,7 @@ subroutine writeincrement_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate
! t increment
call read_vardata(dsfg, 'tmp', tmp, ncstart=ncstart, nccount=nccount, errcode=iret)
if (iret /= 0) then
- print *,'error reading tmp'
+ write(6,*)'WRITEINCREMENT_PNC: ***FATAL ERROR*** reading tmp, iret= ',iret,' PROGRAM STOPS'
call stop2(29)
endif
tv = tmp * ( 1.0 + fv*q)
@@ -4094,33 +4797,68 @@ subroutine writeincrement_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate
call nccheck_incr(nf90_put_var(ncid_out, o3varid, sngl(inc3dout), &
start = ncstart, count = nccount))
+ ! For hydrometeors, following the treatment for specific humidity increment
+ ! Need to make sure the analysis value is not negative
+ ! Read in background + increment and make sure the minimum is qcmin
+ ! Adjust increment accordingly
+
! liq wat increment
! icmr increment
+ ! if cw increment, make sure split the cw increment into ql and qi increments
+ allocate(q2(nlons,nlats,nccount(3)),qanl2(nlons,nlats,nccount(3)))
+ call read_vardata(dsfg, 'clwmr', q, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if (iret /= 0) then
+ write(6,*)'WRITEINCREMENT_PNC: ***FATAL ERROR*** reading clwmr, iret= ',iret,' PROGRAM STOPS'
+ call stop2(29)
+ endif
+ call read_vardata(dsfg, 'icmr', q2, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if (iret /= 0) then
+ write(6,*)'WRITEINCREMENT_PNC: ***FATAL ERROR*** reading icmr, iret= ',iret,' PROGRAM STOPS'
+ call stop2(29)
+ endif
do k=lev_pe1(iope), lev_pe2(iope)
krev = nlevs-k+1
ki = k - lev_pe1(iope) + 1
- ug = zero
+ ug = zero; vg = zero
if (cw_ind > 0) then
call copyfromgrdin(grdin(:,levels(cw_ind-1)+krev,nb,ne),ug)
+ else if (ql_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(ql_ind-1)+krev,nb,ne),ug)
end if
- if (imp_physics == 11) then
- work = -r0_05 * (reshape(tmpanl(:,:,ki),(/nlons*nlats/)) - t0c)
- do i=1,nlons*nlats
- work(i) = max(zero,work(i))
- work(i) = min(one,work(i))
- enddo
- vg = ug * work ! cloud ice
- ug = ug * (one - work) ! cloud water
- inc3d2(:,:,ki) = reshape(vg,(/nlons,nlats/))
+ ! analysis control variable is cw, need to split cw analysis to ql and qi
+ if (cw_ind > 0) then
+ if (imp_physics == 11) then
+ work = -r0_05 * (reshape(tmpanl(:,:,ki),(/nlons*nlats/)) - t0c)
+ do i=1,nlons*nlats
+ work(i) = max(zero,work(i))
+ work(i) = min(one,work(i))
+ enddo
+ vg = ug * work ! cloud ice
+ ug = ug * (one - work) ! cloud water
+ endif
+ else if (qi_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(qi_ind-1)+krev,nb,ne),vg)
endif
- inc3d(:,:,ki) = reshape(ug,(/nlons,nlats/))
+ inc3d(:,:,ki) = reshape(ug,(/nlons,nlats/)) ! cloud water
+ qanl(:,:,ki) = q(:,:,ki) + inc3d(:,:,ki)
+ inc3d2(:,:,ki) = reshape(vg,(/nlons,nlats/)) ! cloud ice
+ qanl2(:,:,ki) = q2(:,:,ki) + inc3d(:,:,ki)
enddo
+
+ ! adjust hydrometeor increment to make sure analysis is positive
+ if (cliptracers) where (qanl < qcmin) qanl = qcmin
+ inc3d = qanl - q ! ql
+ if (cliptracers) where (qanl2 < qcmin) qanl2 = qcmin
+ inc3d2 = qanl2 - q2 ! qi
+
+ ! output ql increment
do j=1,nlats
inc3dout(:,nlats-j+1,:) = inc3d(:,j,:)
end do
if (should_zero_increments_for('liq_wat_inc')) inc3dout = zero
call nccheck_incr(nf90_put_var(ncid_out, liqwatvarid, sngl(inc3dout), &
start = ncstart, count = nccount))
+ ! output qi increment
do j=1,nlats
inc3dout(:,nlats-j+1,:) = inc3d2(:,j,:)
end do
@@ -4128,16 +4866,345 @@ subroutine writeincrement_pnc(vars3d,vars2d,n3d,n2d,levels,ndim,grdin,no_inflate
call nccheck_incr(nf90_put_var(ncid_out, icvarid, sngl(inc3dout), &
start = ncstart, count = nccount))
+ ! rwmr increment
+ call read_vardata(dsfg, 'rwmr', q, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if (iret /= 0) then
+ write(6,*)'WRITEINCREMENT_PNC: ***FATAL ERROR*** reading rwmr, iret= ',iret,' PROGRAM STOPS'
+ call stop2(29)
+ endif
+ do k=lev_pe1(iope), lev_pe2(iope)
+ krev = nlevs-k+1
+ ki = k - lev_pe1(iope) + 1
+ inc(:) = zero
+ if (qr_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(qr_ind-1) + krev,nb,ne),inc)
+ endif
+ inc3d(:,:,ki) = reshape(inc,(/nlons,nlats/))
+ qanl(:,:,ki) = q(:,:,ki) + inc3d(:,:,ki)
+ end do
+ if (cliptracers) where (qanl < qcmin) qanl = qcmin
+ inc3d = qanl - q ! updated rwmr increment
+ do j=1,nlats
+ inc3dout(:,nlats-j+1,:) = inc3d(:,j,:)
+ end do
+ if (should_zero_increments_for('rwmr_inc')) inc3dout = zero
+ call nccheck_incr(nf90_put_var(ncid_out, rwmrvarid, sngl(inc3dout), &
+ start = ncstart, count = nccount))
+
+ ! snmr increment
+ call read_vardata(dsfg, 'snmr', q, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if (iret /= 0) then
+ write(6,*)'WRITEINCREMENT_PNC: ***FATAL ERROR*** reading snmr, iret= ',iret,' PROGRAM STOPS'
+ call stop2(29)
+ endif
+ do k=lev_pe1(iope), lev_pe2(iope)
+ krev = nlevs-k+1
+ ki = k - lev_pe1(iope) + 1
+ inc(:) = zero
+ if (qs_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(qs_ind-1) + krev,nb,ne),inc)
+ endif
+ inc3d(:,:,ki) = reshape(inc,(/nlons,nlats/))
+ qanl(:,:,ki) = q(:,:,ki) + inc3d(:,:,ki)
+ end do
+ if (cliptracers) where (qanl < qcmin) qanl = qcmin
+ inc3d = qanl - q ! updated snmr increment
+ do j=1,nlats
+ inc3dout(:,nlats-j+1,:) = inc3d(:,j,:)
+ end do
+ if (should_zero_increments_for('snmr_inc')) inc3dout = zero
+ call nccheck_incr(nf90_put_var(ncid_out, snmrvarid, sngl(inc3dout), &
+ start = ncstart, count = nccount))
+
+ ! grle increment
+ call read_vardata(dsfg, 'grle', q, ncstart=ncstart, nccount=nccount, errcode=iret)
+ if (iret /= 0) then
+ write(6,*)'WRITEINCREMENT_PNC: ***FATAL ERROR*** reading grle, iret= ',iret,' PROGRAM STOPS'
+ call stop2(29)
+ endif
+ do k=lev_pe1(iope), lev_pe2(iope)
+ krev = nlevs-k+1
+ ki = k - lev_pe1(iope) + 1
+ inc(:) = zero
+ if (qg_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(qg_ind-1) + krev,nb,ne),inc)
+ endif
+ inc3d(:,:,ki) = reshape(inc,(/nlons,nlats/))
+ qanl(:,:,ki) = q(:,:,ki) + inc3d(:,:,ki)
+ end do
+ if (cliptracers) where (qanl < qcmin) qanl = qcmin
+ inc3d = qanl - q ! updated grle increment
+ do j=1,nlats
+ inc3dout(:,nlats-j+1,:) = inc3d(:,j,:)
+ end do
+ if (should_zero_increments_for('grle_inc')) inc3dout = zero
+ call nccheck_incr(nf90_put_var(ncid_out, grlevarid, sngl(inc3dout), &
+ start = ncstart, count = nccount))
+
call mpi_barrier(iocomms(mem_pe(nproc)), iret)
! deallocate things
deallocate(inc3d,inc3d2,inc3dout)
deallocate(tmp,tv,q,tmpanl,tvanl,qanl)
+ deallocate(q2,qanl2)
if (allocated(delzb)) deallocate(delzb)
if (allocated(psges)) deallocate(psges)
+ !closing file
+ call nccheck_incr(nf90_close(ncid_out))
end do backgroundloop ! loop over backgrounds to write out
+ if (nproc == 0) then
+ t2 = mpi_wtime()
+ print *,'time in writeincrement_pnc atm_file on root',t2-t1,'secs'
+ endif
+ end if ! if (write_atm_file)
+
+ if (write_sfc_file ) then
+
+ if (nproc == 0) t1 = mpi_wtime()
+
+ tmp2m_ind = getindex(vars2d, 't2m') !< indices in the state or control var arrays
+ spfh2m_ind = getindex(vars2d, 'q2m')
+ soilt1_ind = getindex(vars2d, 'st1')
+ slc1_ind = getindex(vars2d, 'sl1')
+ soilt2_ind = getindex(vars2d, 'st2')
+ slc2_ind = getindex(vars2d, 'sl2')
+ soilt3_ind = getindex(vars2d, 'st3')
+ slc3_ind = getindex(vars2d, 'sl3')
+ soilt4_ind = getindex(vars2d, 'st4')
+ slc4_ind = getindex(vars2d, 'sl4')
+
+ ! loop through times and do the read
+ ne = 1
+ write(charnanal,'(i3.3)') nanal
+ sfcbackgroundloop: do nb=1,nbackgrounds
+
+ if(no_inflate_flag) then
+ filenameout = trim(adjustl(datapath))//trim(adjustl(incsfcfileprefixes(nb)))//"nimem"//charnanal
+ else
+ filenameout = trim(adjustl(datapath))//trim(adjustl(incsfcfileprefixes(nb)))//"mem"//charnanal
+ end if
+ filenamein = trim(adjustl(datapath))//trim(adjustl(fgsfcfileprefixes(nb)))//"mem"//charnanal
+
+ !! note: only iope=0 is writing the outputs. Having all pes in iocomm write to a file slows it down.
+ !!
+ if (iope==0) then
+ dsfg = open_dataset(filenamein)
+ ! create the output netCDF increment file
+ call nccheck_incr(nf90_create(path=trim(filenameout), cmode=nf90_netcdf4,ncid=ncid_out))
+
+ ! create dimensions based on analysis resolution, not guess
+ call nccheck_incr(nf90_def_dim(ncid_out, "longitude", nlons, lon_dimid))
+ call nccheck_incr(nf90_def_dim(ncid_out, "latitude", nlats, lat_dimid))
+ dimids2 = (/ lon_dimid, lat_dimid /)
+ ! create variables
+ call nccheck_incr(nf90_def_var(ncid_out, "longitude", nf90_real,(/lon_dimid/), lonvarid))
+ call nccheck_incr(nf90_def_var(ncid_out, "latitude", nf90_real,(/lat_dimid/), latvarid))
+ call nccheck_incr(nf90_def_var(ncid_out, "tmp2m_inc", nf90_real, dimids2,tmp2mvarid))
+ call nccheck_incr(nf90_def_var(ncid_out, "spfh2m_inc", nf90_real, dimids2,spfh2mvarid))
+ call nccheck_incr(nf90_def_var(ncid_out, "soilt1_inc", nf90_real, dimids2,soilt1varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "soilt2_inc", nf90_real, dimids2,soilt2varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "soilt3_inc", nf90_real, dimids2,soilt3varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "soilt4_inc", nf90_real, dimids2,soilt4varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "slc1_inc", nf90_real, dimids2,slc1varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "slc2_inc", nf90_real, dimids2,slc2varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "slc3_inc", nf90_real, dimids2,slc3varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "slc4_inc", nf90_real, dimids2,slc4varid))
+ call nccheck_incr(nf90_def_var(ncid_out, "soilsnow_mask", nf90_int,dimids2, maskvarid))
+ ! place global attributes to serial calc_increment output
+ call nccheck_incr(nf90_put_att(ncid_out, nf90_global, "source", "GSI EnKF"))
+ call nccheck_incr(nf90_put_att(ncid_out, nf90_global, "comment", &
+ "global landsfc anal increment from writeincrement"))
+ call nccheck_incr(nf90_put_att(ncid_out, nf90_global, "analysis_time",iadateout))
+ call nccheck_incr(nf90_put_att(ncid_out, nf90_global,"IAU_hour_from_guess", nhr_anal(nb)))
+ ! add units to lat/lon because that's what the calc_increment utility has
+ call nccheck_incr(nf90_put_att(ncid_out, lonvarid, "units","degrees_east"))
+ call nccheck_incr(nf90_put_att(ncid_out, latvarid, "units","degrees_north"))
+ ! end the netCDF file definition
+ call nccheck_incr(nf90_enddef(ncid_out))
+
+ ! longitudes
+ call read_vardata(dsfg, 'grid_xt', values_1d, errcode=iret)
+ deglons(:) = values_1d
+ call nccheck_incr(nf90_put_var(ncid_out, lonvarid, deglons, &
+ start = (/1/), count = (/nlons/)))
+
+ call read_vardata(dsfg, 'grid_yt', values_1d, errcode=iret)
+ ! latitudes
+ do j=1,nlats
+ deglats(nlats-j+1) = values_1d(j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, latvarid, deglats, &
+ start = (/1/), count = (/nlats/)))
+ ! construct mask (1 - soil, 2 - snow, 0 - not snow)
+ ! note: same logic/threshold used in global_cycle to produce
+ ! mask on model grid.
+ call read_vardata(dsfg, 'soill1', values_2d, errcode=iret)
+ mask = 0
+ do j=1,nlats
+ do i = 1, nlons
+ if (values_2d(i,j) .LT. 1.0) then
+ mask(i,nlats-j+1) = 1
+ endif
+ enddo
+ end do
+ call read_vardata(dsfg, 'weasd', values_2d, errcode=iret)
+ do j=1,nlats
+ do i = 1, nlons
+ if (values_2d(i,j) .GT. 0.001) then
+ mask(i,nlats-j+1) = 2
+ endif
+ enddo
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, maskvarid, mask, &
+ start = ncstart(1:2), count = nccount(1:2)))
+
+ allocate(inc2d(nlons,nlats))
+ allocate(inc2dout(nlons,nlats))
+
+ ! tmp2m increment
+ inc(:) = zero
+ if (tmp2m_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d) + tmp2m_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, tmp2mvarid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! spfh2m increment
+ inc(:) = zero
+ if (spfh2m_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+spfh2m_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, spfh2mvarid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! soilt1 increment
+ inc(:) = zero
+ if (soilt1_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+soilt1_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ inc2dout=0.
+ do j=1,nlats
+ do i = 1, nlons
+ if (mask(i,nlats-j+1) .NE. 0) inc2dout(i,nlats-j+1) = inc2d(i,j)
+ enddo
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, soilt1varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! soilt2 increment
+ inc(:) = zero
+ if (soilt2_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+soilt2_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ inc2dout=0.
+ do j=1,nlats
+ do i = 1, nlons
+ if (mask(i,nlats-j+1) .NE. 0) inc2dout(i,nlats-j+1) = inc2d(i,j)
+ enddo
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, soilt2varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! soilt3 increment
+ inc(:) = zero
+ if (soilt3_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+soilt3_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ inc2dout=0.
+ do j=1,nlats
+ do i = 1, nlons
+ if (mask(i,nlats-j+1) .NE. 0) inc2dout(i,nlats-j+1) = inc2d(i,j)
+ enddo
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, soilt3varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! soilt4 increment
+ inc(:) = zero
+ if (soilt4_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+soilt4_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ inc2dout=0.
+ do j=1,nlats
+ do i = 1, nlons
+ if (mask(i,nlats-j+1) .NE. 0) inc2dout(i,nlats-j+1) = inc2d(i,j)
+ enddo
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, soilt4varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! slc1 increment
+ inc(:) = zero
+ if (slc1_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+slc1_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, slc1varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! slc2 increment
+ inc(:) = zero
+ if (slc2_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+slc2_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, slc2varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! slc3 increment
+ inc(:) = zero
+ if (slc3_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+slc3_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, slc3varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+ ! slc4 increment
+ inc(:) = zero
+ if (slc4_ind > 0) then
+ call copyfromgrdin(grdin(:,levels(n3d)+slc4_ind,nb,ne),inc)
+ endif
+ inc2d(:,:) = reshape(inc,(/nlons,nlats/))
+ do j=1,nlats
+ inc2dout(:,nlats-j+1) = inc2d(:,j)
+ end do
+ call nccheck_incr(nf90_put_var(ncid_out, slc4varid, sngl(inc2dout), &
+ start = ncstart(1:2), count = nccount(1:2)))
+
+ call close_dataset(dsfg,errcode=iret)
+ if (iret/=0) then
+ write(6,*)'gridio/writeincrement_par: problem closing netcdf sfc fg dataset, iret=',iret
+ call stop2(23)
+ endif
+ ! deallocate things
+ deallocate(inc2d,inc2dout)
+
+ call nccheck_incr(nf90_close(ncid_out))
+
+ end if
+
+ end do sfcbackgroundloop ! loop over backgrounds to read in
+ if (nproc == 0) then
+ t2 = mpi_wtime()
+ print *,'time in writeincrement_pnc sfc_file on root',t2-t1,'secs'
+ endif
+ endif !write_Sfc
+
! remove the sub communicators
call mpi_barrier(iocomms(mem_pe(nproc)), iret)
call mpi_comm_free(iocomms(mem_pe(nproc)), iret)
@@ -4163,6 +5230,64 @@ end subroutine copyfromgrdin
end subroutine writeincrement_pnc
+ subroutine set_ncio_file_flags(vars3d, n3d, vars2d, n2d, sfc_file, atm_file)
+ ! determine if variables are in sfc and/or atm file, for ncio case.
+ character(len=max_varname_length), dimension(n2d), intent(in) :: vars2d
+ character(len=max_varname_length), dimension(n3d), intent(in) :: vars3d
+ integer, intent(in) :: n2d, n3d
+ logical, intent(out) :: sfc_file, atm_file
+
+ integer(i_kind) :: u_ind, v_ind, tv_ind, q_ind, oz_ind, cw_ind
+ integer(i_kind) :: qr_ind, qs_ind, qg_ind
+ integer(i_kind) :: tsen_ind, ql_ind, qi_ind, prse_ind
+ integer(i_kind) :: ps_ind, pst_ind, sst_ind
+ integer(i_kind) :: tmp2m_ind, spfh2m_ind, soilt1_ind, soilt2_ind, soilt3_ind
+ integer(i_kind) :: soilt4_ind,slc1_ind, slc2_ind, slc3_ind, slc4_ind
+
+ ! atmos file variables
+ u_ind = getindex(vars3d, 'u') !< indices in the state or control var arrays
+ v_ind = getindex(vars3d, 'v') ! U and V (3D)
+ tv_ind = getindex(vars3d, 'tv') ! Tv (3D)
+ q_ind = getindex(vars3d, 'q') ! Q (3D)
+ oz_ind = getindex(vars3d, 'oz') ! Oz (3D)
+ cw_ind = getindex(vars3d, 'cw') ! CW (3D)
+ tsen_ind = getindex(vars3d, 'tsen') !sensible T (3D)
+ ql_ind = getindex(vars3d, 'ql') ! QL (3D)
+ qi_ind = getindex(vars3d, 'qi') ! QI (3D)
+ prse_ind = getindex(vars3d, 'prse')
+ qr_ind = getindex(vars3d, 'qr') ! QR (3D)
+ qs_ind = getindex(vars3d, 'qs') ! QS (3D)
+ qg_ind = getindex(vars3d, 'qg') ! QG (3D)
+ ps_ind = getindex(vars2d, 'ps') ! Ps (2D)
+ pst_ind = getindex(vars2d, 'pst') ! Ps tendency (2D) // equivalent of
+ ! old logical massbal_adjust, if non-zero
+ sst_ind = getindex(vars2d, 'sst') ! is this really in the atmos file?
+
+ ! for nc gfs io determine if requested variables are in sfc and/or atmos file
+ atm_file = ( u_ind>0 .or. v_ind>0 .or. tv_ind>0 .or. q_ind>0 .or. sst_ind>0 .or. &
+ oz_ind>0 .or. cw_ind>0 .or. tsen_ind>0 .or. ql_ind>0 .or. &
+ qi_ind>0 .or. prse_ind>0 .or. qr_ind>0 .or. qs_ind>0 .or. qg_ind>0 )
+
+ ! sfc file variables
+ tmp2m_ind = getindex(vars2d, 't2m')
+ spfh2m_ind = getindex(vars2d, 'q2m')
+ soilt1_ind = getindex(vars2d, 'st1')
+ slc1_ind = getindex(vars2d, 'sl1')
+ soilt2_ind = getindex(vars2d, 'st2')
+ slc2_ind = getindex(vars2d, 'sl2')
+ soilt3_ind = getindex(vars2d, 'st3')
+ slc3_ind = getindex(vars2d, 'sl3')
+ soilt4_ind = getindex(vars2d, 'st4')
+ slc4_ind = getindex(vars2d, 'sl4')
+
+ sfc_file = ( tmp2m_ind > 0 .or. spfh2m_ind > 0 .or. soilt1_ind > 0 .or. &
+ slc1_ind > 0 .or. soilt2_ind > 0 .or. slc2_ind > 0 .or. &
+ soilt3_ind > 0 .or. slc3_ind > 0 .or. soilt4_ind > 0 .or. &
+ slc4_ind > 0 )
+
+ end subroutine set_ncio_file_flags
+
+
logical function checkfield(field,fields,nrec) result(hasfield)
use nemsio_module, only: nemsio_charkind
integer, intent(in) :: nrec
diff --git a/src/enkf/inflation.f90 b/src/enkf/inflation.f90
index 225967028c..c80cc99c10 100644
--- a/src/enkf/inflation.f90
+++ b/src/enkf/inflation.f90
@@ -71,13 +71,14 @@ module inflation
analpertwtnh_rtpp,analpertwtsh_rtpp,analpertwttr_rtpp,&
latbound, delat, datapath, covinflatemax, save_inflation, &
covinflatemin, nlons, nlats, smoothparm, nbackgrounds,&
- covinflatenh,covinflatesh,covinflatetr,lnsigcovinfcutoff
+ covinflatenh,covinflatesh,covinflatetr,lnsigcovinfcutoff,taperanalperts
use kinds, only: r_single, i_kind
use mpeu_util, only: getindex
use constants, only: one, zero, rad2deg, deg2rad
use covlocal, only: latval, taper
-use controlvec, only: ncdim, cvars3d, cvars2d, nc3d, nc2d, clevels
-use gridinfo, only: latsgrd, logp, npts, nlevs_pres
+use controlvec, only: ncdim, cvars3d, cvars2d, nc3d, nc2d, clevels, index_pres
+! note: vars2d_landonly currently only defined for gridio_gfs, but smoothing only coded for gfs.
+use gridinfo, only: latsgrd, logp, npts, nlevs_pres, vars2d_landonly, taper_vert
use loadbal, only: indxproc, numptsperproc, npts_max, anal_chunk, anal_chunk_prior
use smooth_mod, only: smooth
@@ -101,9 +102,10 @@ subroutine inflate_ens()
real(r_single),dimension(ndiag) :: sumcoslat,suma,suma2,sumi,sumf,sumitot,sumatot, &
sumcoslattot,suma2tot,sumftot
real(r_single) fnanalsml,coslat
-integer(i_kind) i,nn,iunit,ierr,nb,nnlvl,ps_ind
+integer(i_kind) i,k,nlev,nn,iunit,ierr,nb,nnlvl,ps_ind, this_ind, ind
+integer(i_kind), dimension(8) :: soil_index
character(len=500) filename
-real(r_single), allocatable, dimension(:,:) :: tmp_chunk2,covinfglobal
+real(r_single), allocatable, dimension(:,:) :: tmp_chunk2,covinfglobal,store_presmooth
real(r_single) r
fnanalsml = one/(real(nanals-1,r_single))
@@ -111,7 +113,7 @@ subroutine inflate_ens()
if (analpertwtnh_rtpp > 1.e-5_r_single .and. &
analpertwtnh_rtpp > 1.e-5_r_single .and. &
analpertwttr_rtpp > 1.e-5_r_single) then
-if (nproc .eq. 0) print *,'performing RTPP inflation...'
+if (nproc == 0) print *,'performing RTPP inflation...'
nbloop: do nb=1,nbackgrounds ! loop over time levels in background
! First perform RTPP ensemble inflation,
! as first described in:
@@ -137,7 +139,7 @@ subroutine inflate_ens()
abs(analpertwttr) < 1.e-5_r_single .and. &
abs(analpertwtsh) < 1.e-5_r_single) return
-if (nproc .eq. 0) print *,'performing RTPS inflation...'
+if (nproc == 0) print *,'performing RTPS inflation...'
! now perform RTPS inflation
nbloop2: do nb=1,nbackgrounds ! loop over time levels in background
@@ -231,7 +233,33 @@ subroutine inflate_ens()
do nn=1,ncdim
call mpi_allreduce(mpi_in_place,covinfglobal(1,nn),npts,mpi_real4,mpi_sum,mpi_comm_world,ierr)
enddo
+ ! do not apply smoothing to soil temp. or soil moisture (not globally defined)
+
+ ind = 0
+ do i = 1,8
+ this_ind = getindex(cvars2d, vars2d_landonly(i))
+ if (this_ind>0) then
+ ind=ind+1
+ soil_index(ind)=this_ind
+ endif
+ enddo
+
+ if (ind>0) then
+ allocate(store_presmooth(npts,ind))
+ do i = 1, ind
+ store_presmooth(:,i) = covinfglobal(:,clevels(nc3d)+soil_index(i))
+ enddo
+ endif
+
call smooth(covinfglobal)
+
+ if (ind>0) then
+ do i = 1, ind
+ covinfglobal(:,clevels(nc3d) + soil_index(i)) = store_presmooth(:,i)
+ enddo
+ deallocate(store_presmooth)
+ endif
+
where (covinfglobal < covinflatemin) covinfglobal = covinflatemin
where (covinfglobal > covinflatemax) covinfglobal = covinflatemax
do i=1,numptsperproc(nproc+1)
@@ -274,11 +302,18 @@ subroutine inflate_ens()
! apply inflation.
do nn=1,ncdim
+ nlev = index_pres(nn) ! vertical index for i'th control variable
+ if (nlev == nlevs+1) nlev=-1 ! 2d field
do i=1,numptsperproc(nproc+1)
! inflate posterior perturbations.
anal_chunk(:,i,nn,nb) = tmp_chunk2(i,nn)*anal_chunk(:,i,nn,nb)
+ ! optionally 'deflate' perturbations to reduce spread near top of model
+ if (taperanalperts .and. nlev > 0) then
+ anal_chunk(:,i,nn,nb) = taper_vert(nlev)*anal_chunk(:,i,nn,nb)
+ endif
+
! area mean surface pressure posterior spread, inflation.
! (this diagnostic only makes sense for grids that are regular in longitude)
if (ps_ind > 0 .and. nn == clevels(nc3d) + ps_ind) then
diff --git a/src/enkf/innovstats.f90 b/src/enkf/innovstats.f90
index e67cf43f10..853532c9b9 100644
--- a/src/enkf/innovstats.f90
+++ b/src/enkf/innovstats.f90
@@ -45,6 +45,7 @@ subroutine print_innovstats(obfit,obsprd)
nobsspd_nh,nobsspd_sh,nobsspd_tr,&
nobsgps_nh,nobsgps_sh,nobsgps_tr,&
nobsdbz_nh,nobsdbz_sh,nobsdbz_tr,&
+ nobsfed_nh,nobsfed_sh,nobsfed_tr,&
nobsrw_nh,nobsrw_sh,nobsrw_tr,&
nobsq_nh,nobsq_sh,nobsq_tr,nobswnd_nh,nobswnd_sh,nobswnd_tr,&
nobsoz_nh,nobsoz_sh,nobsoz_tr,nobsps_sh,nobsps_nh,nobsps_tr,nob
@@ -67,6 +68,9 @@ subroutine print_innovstats(obfit,obsprd)
sumdbz_nh,biasdbz_nh,sumdbz_spread_nh,sumdbz_oberr_nh,&
sumdbz_sh,biasdbz_sh,sumdbz_spread_sh,sumdbz_oberr_sh,&
sumdbz_tr,biasdbz_tr,sumdbz_spread_tr,sumdbz_oberr_tr,&
+ sumfed_nh,biasfed_nh,sumfed_spread_nh,sumfed_oberr_nh,&
+ sumfed_sh,biasfed_sh,sumfed_spread_sh,sumfed_oberr_sh,&
+ sumfed_tr,biasfed_tr,sumfed_spread_tr,sumfed_oberr_tr,&
sumrw_nh,biasrw_nh,sumrw_spread_nh,sumrw_oberr_nh,&
sumrw_sh,biasrw_sh,sumrw_spread_sh,sumrw_oberr_sh,&
sumrw_tr,biasrw_tr,sumrw_spread_tr,sumrw_oberr_tr,&
@@ -112,6 +116,9 @@ subroutine print_innovstats(obfit,obsprd)
nobsdbz_nh = 0
nobsdbz_sh = 0
nobsdbz_tr = 0
+ nobsfed_nh = 0
+ nobsfed_sh = 0
+ nobsfed_tr = 0
nobsrw_nh = 0
nobsrw_sh = 0
nobsrw_tr = 0
@@ -168,6 +175,12 @@ subroutine print_innovstats(obfit,obsprd)
sumdbz_nh,biasdbz_nh,sumdbz_spread_nh,sumdbz_oberr_nh,nobsdbz_nh,&
sumdbz_sh,biasdbz_sh,sumdbz_spread_sh,sumdbz_oberr_sh,nobsdbz_sh,&
sumdbz_tr,biasdbz_tr,sumdbz_spread_tr,sumdbz_oberr_tr,nobsdbz_tr)
+ else if (obtype(nob)(1:3) == 'fed') then
+ call obstats(obfit(nob),oberrvar_orig(nob),&
+ obsprd(nob),obloclat(nob),&
+ sumfed_nh,biasfed_nh,sumfed_spread_nh,sumfed_oberr_nh,nobsfed_nh,&
+ sumfed_sh,biasfed_sh,sumfed_spread_sh,sumfed_oberr_sh,nobsfed_sh,&
+ sumfed_tr,biasfed_tr,sumfed_spread_tr,sumfed_oberr_tr,nobsfed_tr)
else if (obtype(nob)(1:3) == ' rw') then
call obstats(obfit(nob),oberrvar_orig(nob),&
obsprd(nob),obloclat(nob),&
@@ -213,9 +226,12 @@ subroutine print_innovstats(obfit,obsprd)
call printstats(' all gps',sumgps_nh,biasq_nh,sumgps_spread_nh,sumgps_oberr_nh,nobsgps_nh,&
sumgps_sh,biasgps_sh,sumgps_spread_sh,sumgps_oberr_sh,nobsgps_sh,&
sumgps_tr,biasgps_tr,sumgps_spread_tr,sumgps_oberr_tr,nobsgps_tr)
- call printstats(' all dbz',sumdbz_nh,biasq_nh,sumdbz_spread_nh,sumdbz_oberr_nh,nobsdbz_nh,&
+ call printstats(' all dbz',sumdbz_nh,biasdbz_nh,sumdbz_spread_nh,sumdbz_oberr_nh,nobsdbz_nh,&
sumdbz_sh,biasdbz_sh,sumdbz_spread_sh,sumdbz_oberr_sh,nobsdbz_sh,&
sumdbz_tr,biasdbz_tr,sumdbz_spread_tr,sumdbz_oberr_tr,nobsdbz_tr)
+ call printstats(' all fed',sumfed_nh,biasfed_nh,sumfed_spread_nh,sumfed_oberr_nh,nobsfed_nh,&
+ sumfed_sh,biasfed_sh,sumfed_spread_sh,sumfed_oberr_sh,nobsfed_sh,&
+ sumfed_tr,biasfed_tr,sumfed_spread_tr,sumfed_oberr_tr,nobsfed_tr)
call printstats(' all rw',sumrw_nh,biasq_nh,sumrw_spread_nh,sumrw_oberr_nh,nobsrw_nh,&
sumrw_sh,biasrw_sh,sumrw_spread_sh,sumrw_oberr_sh,nobsrw_sh,&
sumrw_tr,biasrw_tr,sumrw_spread_tr,sumrw_oberr_tr,nobsrw_tr)
diff --git a/src/enkf/letkf.f90 b/src/enkf/letkf.f90
index 9b74cecd75..dcd68be8ff 100644
--- a/src/enkf/letkf.f90
+++ b/src/enkf/letkf.f90
@@ -172,8 +172,8 @@ subroutine letkf_update()
if (nproc == 0) print *,'using',nthreads,' openmp threads'
! define a few frequently used parameters
-r_nanals=one/float(nanals)
-r_nanalsm1=one/float(nanals-1)
+r_nanals=one/real(nanals,r_kind)
+r_nanalsm1=one/real(nanals-1,r_kind)
mincorrlength_factsq = mincorrlength_fact**2
kdobs=associated(kdtree_obs2)
@@ -541,31 +541,34 @@ subroutine letkf_update()
enddo
!$omp end parallel do
+tmean=zero
+tmin=zero
+tmax=zero
tend = mpi_wtime()
call mpi_reduce(tend-tbegin,tmean,1,mpi_real8,mpi_sum,0,mpi_comm_world,ierr)
-tmean = tmean/numproc
+tmean = tmean/real(numproc,r_kind)
call mpi_reduce(tend-tbegin,tmin,1,mpi_real8,mpi_min,0,mpi_comm_world,ierr)
call mpi_reduce(tend-tbegin,tmax,1,mpi_real8,mpi_max,0,mpi_comm_world,ierr)
if (nproc .eq. 0) print *,'min/max/mean time to do letkf update ',tmin,tmax,tmean
t2 = t2/nthreads; t3 = t3/nthreads; t4 = t4/nthreads; t5 = t5/nthreads
if (nproc == 0) print *,'time to process analysis on gridpoint = ',t2,t3,t4,t5,' secs on task',nproc
call mpi_reduce(t2,tmean,1,mpi_real8,mpi_sum,0,mpi_comm_world,ierr)
-tmean = tmean/numproc
+tmean = tmean/real(numproc,r_kind)
call mpi_reduce(t2,tmin,1,mpi_real8,mpi_min,0,mpi_comm_world,ierr)
call mpi_reduce(t2,tmax,1,mpi_real8,mpi_max,0,mpi_comm_world,ierr)
if (nproc .eq. 0) print *,',min/max/mean t2 = ',tmin,tmax,tmean
call mpi_reduce(t3,tmean,1,mpi_real8,mpi_sum,0,mpi_comm_world,ierr)
-tmean = tmean/numproc
+tmean = tmean/real(numproc,r_kind)
call mpi_reduce(t3,tmin,1,mpi_real8,mpi_min,0,mpi_comm_world,ierr)
call mpi_reduce(t3,tmax,1,mpi_real8,mpi_max,0,mpi_comm_world,ierr)
if (nproc .eq. 0) print *,',min/max/mean t3 = ',tmin,tmax,tmean
call mpi_reduce(t4,tmean,1,mpi_real8,mpi_sum,0,mpi_comm_world,ierr)
-tmean = tmean/numproc
+tmean = tmean/real(numproc,r_kind)
call mpi_reduce(t4,tmin,1,mpi_real8,mpi_min,0,mpi_comm_world,ierr)
call mpi_reduce(t4,tmax,1,mpi_real8,mpi_max,0,mpi_comm_world,ierr)
if (nproc .eq. 0) print *,',min/max/mean t4 = ',tmin,tmax,tmean
call mpi_reduce(t5,tmean,1,mpi_real8,mpi_sum,0,mpi_comm_world,ierr)
-tmean = tmean/numproc
+tmean = tmean/real(numproc,r_kind)
call mpi_reduce(t5,tmin,1,mpi_real8,mpi_min,0,mpi_comm_world,ierr)
call mpi_reduce(t5,tmax,1,mpi_real8,mpi_max,0,mpi_comm_world,ierr)
if (nproc .eq. 0) print *,',min/max/mean t5 = ',tmin,tmax,tmean
@@ -590,7 +593,7 @@ subroutine letkf_update()
call mpi_reduce(nobslocal_max,nobslocal_maxall,1,mpi_integer,mpi_max,0,mpi_comm_world,ierr)
call mpi_reduce(nobslocal_min,nobslocal_minall,1,mpi_integer,mpi_min,0,mpi_comm_world,ierr)
call mpi_reduce(nobslocal_mean,nobslocal_meanall,1,mpi_integer,mpi_sum,0,mpi_comm_world,ierr)
- if (nproc == 0) print *,'min/max/mean number of obs in local volume',nobslocal_minall,nobslocal_maxall,nint(nobslocal_meanall/float(numproc))
+ if (nproc == 0) print *,'min/max/mean number of obs in local volume',nobslocal_minall,nobslocal_maxall,nint(nobslocal_meanall/real(numproc,r_kind))
endif
call mpi_reduce(nobslocal_max,nobslocal_maxall,1,mpi_integer,mpi_max,0,mpi_comm_world,ierr)
call mpi_reduce(nobslocal_min,nobslocal_minall,1,mpi_integer,mpi_max,0,mpi_comm_world,ierr)
diff --git a/src/enkf/observer_gfs.f90 b/src/enkf/observer_gfs.f90
index 983b25f959..07e4f58457 100644
--- a/src/enkf/observer_gfs.f90
+++ b/src/enkf/observer_gfs.f90
@@ -66,7 +66,7 @@ subroutine setup_linhx(rlat, rlon, time, ix, delx, ixp, delxp, iy, dely, &
!$$$
use kinds, only: r_kind,i_kind,r_single
use params, only: nstatefields, nlons, nlats, nhr_state, fhr_assim
- use gridinfo, only: latsgrd, lonsgrd
+ use gridinfo, only: latsgrd, lonsgrd, npts
use constants, only: zero,one,pi
use mpisetup
implicit none
@@ -76,6 +76,7 @@ subroutine setup_linhx(rlat, rlon, time, ix, delx, ixp, delxp, iy, dely, &
real(r_single) ,intent(in ) :: time ! observation time relative to middle of window
integer(i_kind), intent(out) :: ix, iy, it, ixp, iyp, itp
real(r_kind), intent(out) :: delx, dely, delxp, delyp, delt, deltp
+ integer(i_kind) :: ixnlons
! find interplation indices and deltas
@@ -87,17 +88,21 @@ subroutine setup_linhx(rlat, rlon, time, ix, delx, ixp, delxp, iy, dely, &
ix = min(ix, nlats-1)
ixp = max(ix-1, 0)
+ ixnlons = ix*nlons
+
if (ixp /= ix) then
- delx = (rlat - latsgrd(ix*nlons+1)) / (latsgrd(ixp*nlons + 1) - latsgrd(ix*nlons+1))
+ delx = (rlat - latsgrd(ixnlons+1)) / (latsgrd(ixp*nlons + 1) - latsgrd(ixnlons+1))
else
delx = one
endif
delx = max(zero,min(delx,one))
- iyp = 1
- do while (iyp <= nlons .and. lonsgrd(ix*nlons + iyp) <= rlon)
- iyp = iyp + 1
+ iyp=1
+ do while(iyp <= nlons .and. ixnlons+iyp <= npts)
+ if (lonsgrd(ixnlons+iyp) > rlon) exit
+ iyp = iyp + 1
enddo
+
iy = iyp - 1
if(iy < 1) iy = iy + nlons
if(iyp > nlons) iyp = iyp - nlons
diff --git a/src/enkf/params.f90 b/src/enkf/params.f90
index 593e5a5ec4..f2a52d9a1a 100644
--- a/src/enkf/params.f90
+++ b/src/enkf/params.f90
@@ -85,7 +85,9 @@ module params
character(len=120),dimension(7),public :: statefileprefixes
character(len=120),dimension(7),public :: statesfcfileprefixes
character(len=120),dimension(7),public :: anlfileprefixes
+character(len=120),dimension(7),public :: anlsfcfileprefixes
character(len=120),dimension(7),public :: incfileprefixes
+character(len=120),dimension(7),public :: incsfcfileprefixes
! analysis date string (YYYYMMDDHH)
character(len=10), public :: datestring
! Hour for datestring
@@ -122,6 +124,8 @@ module params
real(r_single),public :: lnsigcutoffnh,lnsigcutofftr,lnsigcutoffsh,&
lnsigcutoffsatnh,lnsigcutoffsattr,lnsigcutoffsatsh,&
lnsigcutoffpsnh,lnsigcutoffpstr,lnsigcutoffpssh
+real(r_single),public :: corrlengthfednh,corrlengthfedtr,corrlengthfedsh, &
+ lnsigcutofffednh,lnsigcutofffedtr,lnsigcutofffedsh
real(r_single),public :: corrlengthrdrnh,corrlengthrdrtr,corrlengthrdrsh, &
lnsigcutoffrdrnh,lnsigcutoffrdrtr,lnsigcutoffrdrsh
real(r_single),public :: analpertwtnh,analpertwtsh,analpertwttr,sprd_tol,saterrfact
@@ -224,12 +228,6 @@ module params
! EFSOI calculation applications
logical,public :: efsoi_flag = .false.
-! if true, use ensemble mean qsat in definition of
-! normalized humidity analysis variable (instead of
-! qsat for each member, which is the default behavior
-! when pseudo_rh=.true. If pseudo_rh=.false, use_qsatensmean
-! is ignored.
-logical,public :: use_qsatensmean = .false.
logical,public :: write_spread_diag = .false.
! if true, use jacobian from GSI stored in diag file to compute
! ensemble perturbations in observation space.
@@ -256,17 +254,24 @@ module params
! write ensemble mean analysis (or analysis increment)
logical,public :: write_ensmean = .false.
+! taper analysis ens perturbations at top of model (gfs only)
+logical, public :: taperanalperts = .false.
+real(r_kind), public :: taperanalperts_akbot = 500.0_r_kind
+real(r_kind), public :: taperanalperts_aktop = -1.0_r_kind
+
namelist /nam_enkf/datestring,datapath,iassim_order,nvars,&
covinflatemax,covinflatemin,deterministic,sortinc,&
mincorrlength_fact,corrlengthnh,corrlengthtr,corrlengthsh,&
- varqc,huber,nlons,nlats,smoothparm,use_qsatensmean,&
+ varqc,huber,nlons,nlats,smoothparm,&
readin_localization, zhuberleft,zhuberright,&
obtimelnh,obtimeltr,obtimelsh,reducedgrid,&
lnsigcutoffnh,lnsigcutofftr,lnsigcutoffsh,&
lnsigcutoffsatnh,lnsigcutoffsattr,lnsigcutoffsatsh,&
lnsigcutoffpsnh,lnsigcutoffpstr,lnsigcutoffpssh,&
+ corrlengthfednh,corrlengthfedsh,corrlengthfedtr,&
+ lnsigcutofffednh,lnsigcutofffedsh,lnsigcutofffedtr,&
fgfileprefixes,fgsfcfileprefixes,anlfileprefixes, &
- incfileprefixes, &
+ anlsfcfileprefixes,incfileprefixes,incsfcfileprefixes,&
statefileprefixes,statesfcfileprefixes, &
covl_minfact,covl_efold,lupd_obspace_serial,letkf_novlocal,&
analpertwtnh,analpertwtsh,analpertwttr,sprd_tol,&
@@ -286,7 +291,7 @@ module params
fv3_native, paranc, nccompress, write_fv3_incr,incvars_to_zero,write_ensmean, &
corrlengthrdrnh,corrlengthrdrsh,corrlengthrdrtr,&
lnsigcutoffrdrnh,lnsigcutoffrdrsh,lnsigcutoffrdrtr,&
- l_use_enkf_directZDA
+ l_use_enkf_directZDA,taperanalperts,taperanalperts_akbot,taperanalperts_aktop
namelist /nam_wrf/arw,nmm,nmm_restart
namelist /nam_fv3/fv3fixpath,nx_res,ny_res,ntiles,l_pres_add_saved,l_fv3reg_filecombined, &
fv3_io_layout_nx,fv3_io_layout_ny
@@ -321,6 +326,10 @@ subroutine read_namelist()
corrlengthrdrnh = 10
corrlengthrdrtr = 10
corrlengthrdrsh = 10
+! corrlength (km) for GLM flash extent density
+corrlengthfednh = 30_r_single
+corrlengthfedtr = 30_r_single
+corrlengthfedsh = 30_r_single
! read in localization length scales from an external file.
readin_localization = .false.
! min and max inflation.
@@ -345,6 +354,9 @@ subroutine read_namelist()
lnsigcutoffrdrnh = 0.2_r_single ! value for radar
lnsigcutoffrdrtr = 0.2_r_single ! value for radar
lnsigcutoffrdrsh = 0.2_r_single ! value for radar
+lnsigcutofffednh = 2._r_single ! value for GLM flash extent density
+lnsigcutofffedtr = 2._r_single ! value for GLM flash extent density
+lnsigcutofffedsh = 2._r_single ! value for GLM flash extent density
! ob time localization
obtimelnh = 1.e10_r_single
obtimeltr = 1.e10_r_single
@@ -460,8 +472,8 @@ subroutine read_namelist()
! Initialize first-guess and analysis file name prefixes.
! (blank means use default names)
fgfileprefixes = ''; anlfileprefixes=''; statefileprefixes=''
-fgsfcfileprefixes = ''; statesfcfileprefixes=''
-incfileprefixes = ''
+anlsfcfileprefixes=''; fgsfcfileprefixes = ''; statesfcfileprefixes=''
+incfileprefixes = ''; incsfcfileprefixes = ''
! option for including convective clouds in the all-sky
cnvw_option=.false.
@@ -679,10 +691,6 @@ subroutine read_namelist()
letkf_flag) then
print *,'warning: no time localization in LETKF!'
endif
- if ((write_ensmean .and. pseudo_rh) .and. .not. use_qsatensmean) then
- print *,'write_ensmean=T requires use_qsatensmean=T when pseudo_rh=T'
- call stop2(19)
- endif
print *, trim(adjustl(datapath))
@@ -720,7 +728,7 @@ subroutine read_namelist()
endif
endif
if (trim(fgsfcfileprefixes(nbackgrounds+1)) .eq. "") then
- fgsfcfileprefixes(nbackgrounds+1)="sfgsfc_"//datestring//"_fhr"//charfhr_anal(nbackgrounds+1)//"_"
+ fgsfcfileprefixes(nbackgrounds+1)="bfg_"//datestring//"_fhr"//charfhr_anal(nbackgrounds+1)//"_"
end if
nbackgrounds = nbackgrounds+1
end do
@@ -742,7 +750,7 @@ subroutine read_namelist()
endif
endif
if (trim(statesfcfileprefixes(nstatefields+1)) .eq. "") then
- statesfcfileprefixes(nstatefields+1)="sfgsfc_"//datestring//"_fhr"//charfhr_state(nstatefields+1)//"_"
+ statesfcfileprefixes(nstatefields+1)="bfg_"//datestring//"_fhr"//charfhr_state(nstatefields+1)//"_"
end if
nstatefields = nstatefields+1
end do
@@ -762,6 +770,23 @@ subroutine read_namelist()
incfileprefixes(nb)="incr_"//datestring//"_fhr"//charfhr_anal(nb)//"_"
! else
! anlfileprefixes(nb)="sanl_"//datestring//"_"
+! endif
+ endif
+ endif
+ if (trim(anlsfcfileprefixes(nb)) .eq. "") then
+ ! default analysis file prefix
+ if (regional) then
+ if (nbackgrounds > 1) then
+ anlsfcfileprefixes(nb)="sfc_analysis_fhr"//charfhr_anal(nb)//"."
+ else
+ anlsfcfileprefixes(nb)="sfc_analysis."
+ endif
+ else ! global
+! if (nbackgrounds > 1) then
+ anlsfcfileprefixes(nb)="banl_"//datestring//"_fhr"//charfhr_anal(nb)//"_"
+ incsfcfileprefixes(nb)="sfcincr_"//datestring//"_fhr"//charfhr_anal(nb)//"_"
+! else
+! anlfileprefixes(nb)="sanl_"//datestring//"_"
! endif
endif
endif
@@ -804,6 +829,10 @@ subroutine read_namelist()
corrlengthrdrnh = corrlengthrdrnh * 1.e3_r_single/rearth
corrlengthrdrtr = corrlengthrdrtr * 1.e3_r_single/rearth
corrlengthrdrsh = corrlengthrdrsh * 1.e3_r_single/rearth
+! rescale covariance localization length for GLM FED
+corrlengthfednh = corrlengthfednh * 1.e3_r_single/rearth
+corrlengthfedtr = corrlengthfedtr * 1.e3_r_single/rearth
+corrlengthfedsh = corrlengthfedsh * 1.e3_r_single/rearth
! convert targe area boundary into radians
tar_minlat = tar_minlat * deg2rad
diff --git a/src/enkf/readconvobs.f90 b/src/enkf/readconvobs.f90
index e1977298a6..65db770b6d 100644
--- a/src/enkf/readconvobs.f90
+++ b/src/enkf/readconvobs.f90
@@ -32,7 +32,8 @@ module readconvobs
use kinds, only: r_kind,i_kind,r_single,r_double
use constants, only: one,zero,deg2rad
-use params, only: npefiles, netcdf_diag, modelspace_vloc, l_use_enkf_directZDA
+use params, only: npefiles, netcdf_diag, modelspace_vloc, &
+ l_use_enkf_directZDA
implicit none
private
@@ -40,9 +41,9 @@ module readconvobs
!> observation types to read from netcdf files
-integer(i_kind), parameter :: nobtype = 11
+integer(i_kind), parameter :: nobtype = 12
character(len=3), dimension(nobtype), parameter :: obtypes = (/' t', ' q', ' ps', ' uv', 'tcp', &
- 'gps', 'spd', ' pw', ' dw', ' rw', 'dbz' /)
+ 'gps', 'spd', ' pw', ' dw', ' rw', 'dbz', 'fed' /)
contains
@@ -77,7 +78,7 @@ subroutine get_num_convobs_bin(obspath,datestring,num_obs_tot,num_obs_totdiag,id
integer(i_kind) :: iunit, nchar, nreal, ii, mype, ios, idate, i, ipe, ioff0
integer(i_kind),dimension(2) :: nn,nobst, nobsps, nobsq, nobsuv, nobsgps, &
nobstcp,nobstcx,nobstcy,nobstcz,nobssst, nobsspd, nobsdw, nobsrw, nobspw, &
- nobsdbz
+ nobsdbz, nobsfed
character(8),allocatable,dimension(:):: cdiagbuf
real(r_single),allocatable,dimension(:,:)::rdiagbuf
real(r_kind) :: errorlimit,errorlimit2,error,pres,obmax
@@ -102,6 +103,7 @@ subroutine get_num_convobs_bin(obspath,datestring,num_obs_tot,num_obs_totdiag,id
nobspw = 0
nobsgps = 0
nobsdbz = 0
+ nobsfed = 0
nobstcp = 0; nobstcx = 0; nobstcy = 0; nobstcz = 0
init_pass = .true.
peloop: do ipe=0,npefiles
@@ -185,6 +187,9 @@ subroutine get_num_convobs_bin(obspath,datestring,num_obs_tot,num_obs_totdiag,id
else if (obtype == 'dbz') then
nobsdbz = nobsdbz + nn
num_obs_tot = num_obs_tot + nn(2)
+ else if (obtype == 'fed') then
+ nobsfed = nobsfed + nn
+ num_obs_tot = num_obs_tot + nn(2)
else if (obtype == 'gps') then
nobsgps = nobsgps + nn
num_obs_tot = num_obs_tot + nn(2)
@@ -229,6 +234,7 @@ subroutine get_num_convobs_bin(obspath,datestring,num_obs_tot,num_obs_totdiag,id
write(6,100) 'dw',nobsdw(1),nobsdw(2)
write(6,100) 'rw',nobsrw(1),nobsrw(2)
write(6,100) 'dbz',nobsdbz(1),nobsdbz(2)
+ write(6,100) 'fed',nobsfed(1),nobsfed(2)
write(6,100) 'tcp',nobstcp(1),nobstcp(2)
if (nobstcx(2) .gt. 0) then
write(6,100) 'tcx',nobstcx(1),nobstcx(2)
@@ -329,7 +335,6 @@ subroutine get_num_convobs_nc(obspath,datestring,num_obs_tot,num_obs_totdiag,id)
call nc_diag_read_close(obsfile)
-
num_obs_totdiag = num_obs_totdiag + nobs_curr
do i = 1, nobs_curr
@@ -789,6 +794,9 @@ subroutine get_convobs_data_nc(obspath, datestring, nobs_max, nobs_maxdiag, &
x_obs(nob) = x_obs(nob) /Forecast_Saturation_Spec_Hum(i)
hx_mean(nob) = hx_mean(nob) /Forecast_Saturation_Spec_Hum(i)
hx_mean_nobc(nob) = hx_mean_nobc(nob) /Forecast_Saturation_Spec_Hum(i)
+ if (neigv>0) then
+ hx_modens(:,nob) = hx_modens(:,nob)/ Forecast_Saturation_Spec_Hum(i)
+ endif
endif
! for wind, also read v-component
@@ -1071,6 +1079,7 @@ subroutine get_convobs_data_bin(obspath, datestring, nobs_max, nobs_maxdiag, &
if (obtype == ' t' .or. obtype == ' uv' .or. obtype == ' ps' .or. &
obtype == 'tcp' .or. obtype == ' q' .or. obtype == 'spd' .or. &
obtype == 'sst' .or. obtype == ' rw' .or. obtype == 'dbz' .or. &
+ obtype == 'fed' .or. &
obtype == 'gps' .or. obtype == ' dw' .or. obtype == ' pw') then
! direct reflectivitiy DA has a different routine for dbz obs.
diff --git a/src/enkf/statevec.f90 b/src/enkf/statevec.f90
index d1be91af3c..44ad5df9b4 100644
--- a/src/enkf/statevec.f90
+++ b/src/enkf/statevec.f90
@@ -14,7 +14,7 @@ module statevec
!
! Public Variables:
! nanals: (integer scalar) number of ensemble members (from module params)
-! nlevs: number of analysis vertical levels (from module params).
+! nlevs: number of analysis atmos vertical levels (from module params).
! ns3d: number of 3D variables
! ns2d: number of 2D variables
! svars3d: names of 3D variables
@@ -120,7 +120,7 @@ subroutine init_statevec()
svars3d(ns3d)=trim(adjustl(var))
slevels(ns3d)=ilev + slevels(ns3d-1)
else
- if (nproc .eq. 0) print *,'Error: only ', nlevs, ' and ', nlevs+1,' number of levels is supported in current version, got ',ilev
+ if (nproc .eq. 0) print *,'Error statevec: - only ', nlevs, ' and ', nlevs+1,' number of levels is supported in current version, got ',ilev
call stop2(503)
endif
enddo
@@ -136,7 +136,7 @@ subroutine init_statevec()
do i = 1, ns2d
if (getindex(vars2d_supported, svars2d(i))<0) then
if (nproc .eq. 0) then
- print *,'Error: 2D variable ', svars2d(i), ' is not supported in current version.'
+ print *,'Error: state 2D variable ', svars2d(i), ' is not supported in current version.'
print *,'Supported variables: ', vars2d_supported
endif
call stop2(502)
@@ -145,7 +145,7 @@ subroutine init_statevec()
do i = 1, ns3d
if (getindex(vars3d_supported, svars3d(i))<0) then
if (nproc .eq. 0) then
- print *,'Error: 3D variable ', svars3d(i), ' is not supported in current version.'
+ print *,'Error: state 3D variable ', svars3d(i), ' is not supported in current version.'
print *,'Supported variables: ', vars3d_supported
endif
call stop2(502)
diff --git a/src/gsi/CMakeLists.txt b/src/gsi/CMakeLists.txt
index af94224c05..1afb0774ca 100644
--- a/src/gsi/CMakeLists.txt
+++ b/src/gsi/CMakeLists.txt
@@ -29,6 +29,7 @@ endif()
option(OPENMP "Enable OpenMP Threading" OFF)
option(ENABLE_MKL "Use MKL for LAPACK implementation (if available)" ON)
option(USE_GSDCLOUD "Use GSD Cloud Analysis library" OFF)
+option(USE_MGBF "Use MGBF library" ON)
set(GSI_VALID_MODES "GFS" "Regional")
set(GSI_MODE "GFS" CACHE STRING "Choose the GSI Application.")
@@ -43,6 +44,7 @@ endif()
message(STATUS "GSI: OPENMP ................. ${OPENMP}")
message(STATUS "GSI: ENABLE_MKL ............. ${ENABLE_MKL}")
message(STATUS "GSI: USE_GSDCLOUD ........... ${USE_GSDCLOUD}")
+message(STATUS "GSI: USE_MGBF ............... ${USE_MGBF}")
message(STATUS "GSI: GSI_MODE ............... ${GSI_MODE}")
# Dependencies
@@ -87,6 +89,13 @@ if(USE_GSDCLOUD)
endif()
endif()
+# MGBF library dependency
+if(USE_MGBF)
+ if(NOT TARGET mgbf)
+ find_package(mgbf REQUIRED)
+ endif()
+endif()
+
# Get compiler flags for the GSI application
include(gsiapp_compiler_flags)
@@ -146,6 +155,7 @@ target_link_libraries(gsi_fortran_obj PUBLIC nemsio::nemsio)
target_link_libraries(gsi_fortran_obj PUBLIC ncio::ncio)
target_link_libraries(gsi_fortran_obj PUBLIC w3emc::w3emc_d)
target_link_libraries(gsi_fortran_obj PUBLIC sp::sp_d)
+add_library(crtm::crtm ALIAS crtm)
target_link_libraries(gsi_fortran_obj PUBLIC bufr::bufr_d)
target_link_libraries(gsi_fortran_obj PUBLIC crtm::crtm)
if(GSI_MODE MATCHES "Regional")
@@ -158,6 +168,12 @@ if(USE_GSDCLOUD)
endif()
target_link_libraries(gsi_fortran_obj PUBLIC gsdcloud::gsdcloud)
endif()
+if(USE_MGBF)
+ if(TARGET mgbf)
+ add_dependencies(gsi_fortran_obj mgbf)
+ endif()
+ target_link_libraries(gsi_fortran_obj PUBLIC mgbf::mgbf)
+endif()
if(OpenMP_Fortran_FOUND)
target_link_libraries(gsi_fortran_obj PRIVATE OpenMP::OpenMP_Fortran)
endif()
diff --git a/src/gsi/adjtest.f90 b/src/gsi/adjtest.f90
index d910d14f12..3447dec202 100644
--- a/src/gsi/adjtest.f90
+++ b/src/gsi/adjtest.f90
@@ -33,10 +33,12 @@ module adjtest
use control_vectors, only: control_vector,allocate_cv,random_cv, &
deallocate_cv,dot_product,assignment(=)
use state_vectors, only: allocate_state,deallocate_state,dot_product
+use gridmod, only : minmype
use gsi_bundlemod, only: gsi_bundle
use gsi_bundlemod, only: assignment(=)
use bias_predictors, only: predictors,allocate_preds,deallocate_preds, &
assignment(=)
+use control2state_mod, only: control2state,control2state_ad
implicit none
private
@@ -81,7 +83,7 @@ subroutine adtest(xhat)
integer(i_kind) :: ii,idig
real(r_kind) :: zz1,zz2,zz3
-if (mype==0) write(6,*)'ADTEST starting'
+if (mype==minmype) write(6,*)'ADTEST starting'
! ----------------------------------------------------------------------
! Allocate local variables
@@ -97,10 +99,10 @@ subroutine adtest(xhat)
! Initialize control space vectors
if (present(xhat)) then
xtest1=xhat
- if (mype==0) write(6,*)'ADTEST use input xhat'
+ if (mype==minmype) write(6,*)'ADTEST use input xhat'
else
call random_cv(xtest1)
- if (mype==0) write(6,*)'ADTEST use random_cv(xhat)'
+ if (mype==minmype) write(6,*)'ADTEST use random_cv(xhat)'
endif
xtest2=zero
@@ -135,18 +137,20 @@ subroutine adtest(xhat)
do ii=1,nsubwin
zz2=zz2+dot_product(stest1(ii),stest1(ii))
enddo
-DO ii=1,nrclen
+do ii=1,nrclen
zz2=zz2+sbias1%values(ii)*sbias1%values(ii)
-ENDDO
+enddo
-if ( abs(zz1+zz2) > sqrt(tiny(zz3)) ) then
- zz3=two*abs(zz1-zz2)/(zz1+zz2)
-else
- zz3=abs(zz1-zz2)
-endif
-idig= int(-log(zz3+tiny(zz3))/log(10.0_r_kind))
+if (mype==minmype) then
+ if ( abs(zz1+zz2) > sqrt(tiny(zz3)) ) then
+ zz3=two*abs(zz1-zz2)/(zz1+zz2)
+ else
+ zz3=abs(zz1-zz2)
+ end if
+ idig= int(-log(zz3+tiny(zz3))/log(10.0_r_kind))
-if (mype==0) then
+! Note that this result is not completely correct especially on processors
+! other than minmype. See issue 548.
write(6,'(A)')' ADTEST 0.123456789012345678'
write(6,'(A,ES25.18)')' ADTEST = ',zz1
write(6,'(A,ES25.18)')' ADTEST = ',zz2
@@ -166,7 +170,7 @@ subroutine adtest(xhat)
call deallocate_preds(sbias2)
! ----------------------------------------------------------------------
-if (mype==0) write(6,*)'ADTEST finished'
+if (mype==minmype) write(6,*)'ADTEST finished'
return
end subroutine adtest
diff --git a/src/gsi/adjtest_obs.f90 b/src/gsi/adjtest_obs.f90
index 67e2ff0cdd..294dc32ca0 100644
--- a/src/gsi/adjtest_obs.f90
+++ b/src/gsi/adjtest_obs.f90
@@ -78,6 +78,7 @@ subroutine adtest_obs
use m_obsdiags, only: obsLLists
use m_obsLList, only: obsLList_getTLDdotprod
+ use control2state_mod, only: control2state
implicit none
diff --git a/src/gsi/aeroinfo.f90 b/src/gsi/aeroinfo.f90
index dd8489029b..a030bdeffc 100644
--- a/src/gsi/aeroinfo.f90
+++ b/src/gsi/aeroinfo.f90
@@ -313,12 +313,10 @@ subroutine aeroinfo_read
! Successful read, return to calling routine
else
-! File does not exist, write warning message to alert users
+! File does not exist, write warning message to unit 6 to alert users
if (mype==mype_aero) then
- open(iout_aero)
- write(iout_aero,*)'AEROINFO_READ: ***WARNING*** FILE ',trim(fname),' does not exist'
- write(iout_aero,*)'AEROINFO_READ: jpch_aero=',jpch_aero
- close(iout_aero)
+ write(6,*)'AEROINFO_READ: ***WARNING*** FILE ',trim(fname),' does not exist'
+ write(6,*)'AEROINFO_READ: jpch_aero=',jpch_aero
endif
end if
diff --git a/src/gsi/aircraftinfo.f90 b/src/gsi/aircraftinfo.f90
index b84455f47c..a29f1571b1 100644
--- a/src/gsi/aircraftinfo.f90
+++ b/src/gsi/aircraftinfo.f90
@@ -57,7 +57,7 @@ module aircraftinfo
logical :: cleanup_tail ! logical to remove tail number no longer used
logical :: upd_aircraft ! indicator if update bias at 06Z & 18Z
- integer(i_kind), parameter :: max_tail=10000 ! max tail numbers
+ integer(i_kind), parameter :: max_tail=100000 ! max tail numbers
integer(i_kind) npredt ! predictor number
integer(i_kind) ntail ! total tail number
integer(i_kind) ntail_update ! new total tail number
diff --git a/src/gsi/aniso_ens_util.f90 b/src/gsi/aniso_ens_util.f90
index f118bee40f..43f81216e4 100644
--- a/src/gsi/aniso_ens_util.f90
+++ b/src/gsi/aniso_ens_util.f90
@@ -122,8 +122,8 @@ subroutine ens_uv_to_psichi(u,v,truewind)
do j=1,nlon
rlon=region_lon(i,j)
rlat=region_lat(i,j)
- dlon=float(j)*one
- dlat=float(i)*one
+ dlon=real(j,r_kind)
+ dlat=real(i,r_kind)
ue=u(i,j)
ve=v(i,j)
call rotate_wind_ll2xy(ue,ve,ug,vg,rlon,dlon,dlat)
@@ -440,13 +440,13 @@ subroutine ens_intpcoeffs_reg(ngrds,igbox,iref,jref,igbox0f,ensmask,enscoeff,gbl
yg=rlat+90._r_kind+one
end if
- dxg=xg-float(floor(xg))
- dyg=yg-float(floor(yg))
+ dxg=xg-real(floor(xg),r_kind)
+ dyg=yg-real(floor(yg),r_kind)
dxg1=one-dxg
dyg1=one-dyg
- if (xg>=one .and. xg<=float(jxp) .and. &
- yg>=one .and. yg<=float(iy) ) then
+ if (xg>=one .and. xg<=real(jxp,r_kind) .and. &
+ yg>=one .and. yg<=real(iy,r_kind) ) then
enscoeff(1,i,j,kg)=dxg1*dyg1
enscoeff(2,i,j,kg)=dxg1*dyg
@@ -479,9 +479,9 @@ subroutine ens_intpcoeffs_reg(ngrds,igbox,iref,jref,igbox0f,ensmask,enscoeff,gbl
endif
do j=1,iy
- yg=float(j)*one
+ yg=real(j,r_kind)
do i=1,jx
- xg=float(i)*one
+ xg=real(i,r_kind)
call w3fb12(xg,yg,alat1,elon1,ds,elonv,alatan,rlat,rlon,ierr8)
rlon=rlon/rad2deg
rlat=rlat/rad2deg
@@ -620,34 +620,34 @@ subroutine ens_intpcoeffs_reg(ngrds,igbox,iref,jref,igbox0f,ensmask,enscoeff,gbl
igbox(2,kg)=iimax0(kg)
igbox(3,kg)=jjmin0(kg)
igbox(4,kg)=jjmax0(kg)
- igbox0f(1,kg)=one+float((igbox(1,kg)-1))/pf2aP1%grid_ratio_lat + ijadjust
- igbox0f(2,kg)=one+float((igbox(2,kg)-1))/pf2aP1%grid_ratio_lat - ijadjust
- igbox0f(3,kg)=one+float((igbox(3,kg)-1))/pf2aP1%grid_ratio_lon + ijadjust
- igbox0f(4,kg)=one+float((igbox(4,kg)-1))/pf2aP1%grid_ratio_lon - ijadjust
+ igbox0f(1,kg)=one+real(igbox(1,kg)-1,r_kind)/pf2aP1%grid_ratio_lat + ijadjust
+ igbox0f(2,kg)=one+real(igbox(2,kg)-1,r_kind)/pf2aP1%grid_ratio_lat - ijadjust
+ igbox0f(3,kg)=one+real(igbox(3,kg)-1,r_kind)/pf2aP1%grid_ratio_lon + ijadjust
+ igbox0f(4,kg)=one+real(igbox(4,kg)-1,r_kind)/pf2aP1%grid_ratio_lon - ijadjust
end do
!==> compute blending functions
do i=1,pf2aP1%nlatf
- dist1=float(igbox0f(1,1)-i)
- dist2=float(i-igbox0f(2,1))
+ dist1=real(igbox0f(1,1)-i,r_kind)
+ dist2=real(i-igbox0f(2,1),r_kind)
gblend_b(i,1)=half*(one-tanh(dist1)) !relax to zero
gblend_t(i,1)=half*(one-tanh(dist2)) !outside 212 grid
- dist1=float(igbox0f(1,2)-i)
- dist2=float(i-igbox0f(2,2))
+ dist1=real(igbox0f(1,2)-i,r_kind)
+ dist2=real(i-igbox0f(2,2),r_kind)
gblend_b(i,2)=half*(one-tanh(dist1)) !relax to zero
gblend_t(i,2)=half*(one-tanh(dist2)) !outside 221 grid
end do
do j=1,pf2aP1%nlonf
- dist1=float(igbox0f(3,1)-j)
- dist2=float(j-igbox0f(4,1))
+ dist1=real(igbox0f(3,1)-j,r_kind)
+ dist2=real(j-igbox0f(4,1),r_kind)
gblend_l(j,1)=half*(one-tanh(dist1)) !relax to zero
gblend_r(j,1)=half*(one-tanh(dist2)) !outside 212 grid
- dist1=float(igbox0f(3,2)-j)
- dist2=float(j-igbox0f(4,2))
+ dist1=real(igbox0f(3,2)-j,r_kind)
+ dist2=real(j-igbox0f(4,2),r_kind)
gblend_l(j,2)=half*(one-tanh(dist1)) !relax to zero
gblend_r(j,2)=half*(one-tanh(dist2)) !outside 221 grid
end do
@@ -1141,10 +1141,10 @@ subroutine ens_fill(ur,na,nb,u,nxx,ny,itap,no_wgt_in)
no_wgt=.false.
if(no_wgt_in) no_wgt=.true.
- pionp1=four*atan(one)/float(itap+1)
+ pionp1=four*atan(one)/real(itap+1,r_kind)
do i=1,itap
- xi=float(i)
+ xi=real(i,r_kind)
wt(i)=half+half*cos(pionp1*xi)
enddo
diff --git a/src/gsi/anisofilter.f90 b/src/gsi/anisofilter.f90
index ec05d191ba..c05c764a05 100755
--- a/src/gsi/anisofilter.f90
+++ b/src/gsi/anisofilter.f90
@@ -596,7 +596,7 @@ subroutine anprewgt_reg(mype)
do i=indices%ips,indices%ipe
l =max(min(int(rllatf(i,j)),mlat),1)
lp=min((l+1),mlat)
- dl2=rllatf(i,j)-float(l)
+ dl2=rllatf(i,j)-real(l,r_kind)
dl1=one-dl2
if (ivar <= nrf) then
if (nrf_3d(ivar)) then
@@ -1056,7 +1056,7 @@ subroutine get_aspect_reg_pt(mype)
asp3=scalex3*asp3
endif
- rk1=float(k1-44)
+ rk1=real(k1-44,r_kind)
fblend=half*(one-tanh(rk1))! one
if (nvar_id(k) /= nrf3_loc(nrf3_q)) then
@@ -1126,7 +1126,7 @@ subroutine fact_qopt2(factk,rh,kvar)
d =20.0_r_kind * rh + one
n =int(d)
np =n+1
- dn2=d-float(n)
+ dn2=d-real(n,r_kind)
dn1=one-dn2
n =min0(max(1,n) ,25)
np=min0(max(1,np),25)
@@ -2407,7 +2407,7 @@ subroutine read_bckgstats(mype)
do k=1,nsig
vzimax(k,n)=maxval(one/vz(k,0:mlat+1,n))
vzimin(k,n)=minval(one/vz(k,0:mlat+1,n))
- vziavg(k,n)=sum((one/vz(k,0:mlat+1,n)))/float(mlat+2)
+ vziavg(k,n)=sum((one/vz(k,0:mlat+1,n)))/real(mlat+2,r_kind)
end do
if(print_verbose) then
do k=1,nsig
@@ -2428,13 +2428,13 @@ subroutine read_bckgstats(mype)
do n=1,nrf3
do k=1,nsig
- corzavg(k,n)=sum(corz(1:mlat,k,n))/float(mlat)
- hwllavg(k,n)=sum(hwll(0:mlat+1,k,n))/float(mlat+2)
+ corzavg(k,n)=sum(corz(1:mlat,k,n))/real(mlat,r_kind)
+ hwllavg(k,n)=sum(hwll(0:mlat+1,k,n))/real(mlat+2,r_kind)
end do
end do
do n=1,nvars-nrf3
- corpavg(n)=sum(corp(1:mlat,n))/float(mlat)
- hwllpavg(n)=sum(hwllp(0:mlat+1,n))/float(mlat+2)
+ corpavg(n)=sum(corp(1:mlat,n))/real(mlat,r_kind)
+ hwllpavg(n)=sum(hwllp(0:mlat+1,n))/real(mlat+2,r_kind)
end do
do j=1,mlat
@@ -2869,7 +2869,7 @@ subroutine isotropic_scales(scale1,scale2,scale3,k)
else
l =max(min(int(rllatf(i,j)),mlat),1)
lp=min((l+1),mlat)
- dl2=rllatf(i,j)-float(l)
+ dl2=rllatf(i,j)-real(l,r_kind)
dl1=one-dl2
hwll_loc=dl1*hwll(l,k1,n)+dl2*hwll(lp,k1,n)
end if
@@ -2886,7 +2886,7 @@ subroutine isotropic_scales(scale1,scale2,scale3,k)
l =max(min(int(rllatf(i,j)),mlat),1)
lp=min((l+1),mlat)
- dl2=rllatf(i,j)-float(l)
+ dl2=rllatf(i,j)-real(l,r_kind)
dl1=one-dl2
hwll_loc=cc*(dl1*hwllp(l,n)+dl2*hwllp(lp,n))
scale3(i,j)=one
@@ -2903,7 +2903,7 @@ subroutine isotropic_scales(scale1,scale2,scale3,k)
l =max(min(int(rllatf(i,j)),mlat),1)
lp=min((l+1),mlat)
- dl2=rllatf(i,j)-float(l)
+ dl2=rllatf(i,j)-real(l,r_kind)
dl1=one-dl2
hwll_loc=cc*(dl1*hwllp(l,nn)+dl2*hwllp(lp,nn))
scale3(i,j)=one
@@ -3027,7 +3027,7 @@ subroutine get_theta_corrl_lenghts(mype)
mcount0=lon2*lat2! It's OK to count buffer points
call mpi_allreduce(pbar4a,pbar4(k),1,mpi_real8,mpi_sum,mpi_comm_world,ierror)
call mpi_allreduce(mcount0,mcount,1,mpi_integer4,mpi_sum,mpi_comm_world,ierror)
- pbar4(k)=pbar4(k)/float(mcount)
+ pbar4(k)=pbar4(k)/real(mcount,r_kind)
if(print_verbose) write(6,*)'in get_theta_corrl_lenghts,k,pbar4=',k,pbar4(k)
call w3fa03(pbar4(k),hgt4(k),tbar4(k),thetabar4(k))
end do
@@ -3881,15 +3881,15 @@ subroutine get_aspect_reg_ens(mype)
do j=1,pf2aP1%nlonf
do i=1,pf2aP1%nlatf
- ensv(i,j,k,1)=(ensv(i,j,k,1)+ensv(i,j,k,2)+ensv(i,j,k,3))/sqrt(float(nt1))
- ensv(i,j,k,2)= (ensv(i,j,k,2)+ensv(i,j,k,3))/sqrt(float(nt2))
- ensv(i,j,k,3)= ensv(i,j,k,3) /sqrt(float(nt3))
+ ensv(i,j,k,1)=(ensv(i,j,k,1)+ensv(i,j,k,2)+ensv(i,j,k,3))/sqrt(real(nt1,r_kind))
+ ensv(i,j,k,2)= (ensv(i,j,k,2)+ensv(i,j,k,3))/sqrt(real(nt2,r_kind))
+ ensv(i,j,k,3)= ensv(i,j,k,3) /sqrt(real(nt3,r_kind))
if( ibldani==0 .or. ibldani==2 .or. ibldani==3 ) then
do m=1,6
- c(m,1)=(aniasp(m,i,j,k,1)+aniasp(m,i,j,k,2)+aniasp(m,i,j,k,3))/float(nt1)
- c(m,2)= (aniasp(m,i,j,k,2)+aniasp(m,i,j,k,3))/float(nt2)
- c(m,3)= aniasp(m,i,j,k,3) /float(nt3)
+ c(m,1)=(aniasp(m,i,j,k,1)+aniasp(m,i,j,k,2)+aniasp(m,i,j,k,3))/real(nt1,r_kind)
+ c(m,2)= (aniasp(m,i,j,k,2)+aniasp(m,i,j,k,3))/real(nt2,r_kind)
+ c(m,3)= aniasp(m,i,j,k,3) /real(nt3,r_kind)
end do
do igd=1,3
qlx=max(qlxmin(ivar,k1),ensv(i,j,k,igd))
@@ -3906,9 +3906,9 @@ subroutine get_aspect_reg_ens(mype)
end do
else if(ibldani==1) then
do m=1,6
- aniasp(m,i,j,k,1)=(aniasp(m,i,j,k,1)+aniasp(m,i,j,k,2)+aniasp(m,i,j,k,3))/float(nt1)
- aniasp(m,i,j,k,2)= (aniasp(m,i,j,k,2)+aniasp(m,i,j,k,3))/float(nt2)
- aniasp(m,i,j,k,3)= aniasp(m,i,j,k,3) /float(nt3)
+ aniasp(m,i,j,k,1)=(aniasp(m,i,j,k,1)+aniasp(m,i,j,k,2)+aniasp(m,i,j,k,3))/real(nt1,r_kind)
+ aniasp(m,i,j,k,2)= (aniasp(m,i,j,k,2)+aniasp(m,i,j,k,3))/real(nt2,r_kind)
+ aniasp(m,i,j,k,3)= aniasp(m,i,j,k,3) /real(nt3,r_kind)
end do
smax=real(maxval(ensv(i,j,k,1:3)),r_kind)
aensv(1,k)=aensv(1,k)+max(smax ,qlxmin(ivar,k1))/nlatlonf
@@ -5326,7 +5326,7 @@ subroutine get2berr_reg_subdomain_option(mype)
l=max(min(int(rllatf(i,j)),mlat),1)
lp=min((l+1),mlat)
- dl2=rllatf(i,j)-float(l)
+ dl2=rllatf(i,j)-real(l,r_kind)
dl1=one-dl2
if (ivar <= nrf) then
if (nrf_3d(ivar)) then
@@ -6520,7 +6520,7 @@ subroutine isotropic_scales_subdomain_option(scale1,scale2,scale3,k,mype)
else
l=int(rllat(iglob,jglob))
lp=l+1
- dl2=rllat(iglob,jglob)-float(l)
+ dl2=rllat(iglob,jglob)-real(l,r_kind)
dl1=one-dl2
hwll_loc=dl1*hwll(l,k1,n)+dl2*hwll(lp,k1,n)
scale3(i,j)=one/vz(k1,l,n)
@@ -6536,7 +6536,7 @@ subroutine isotropic_scales_subdomain_option(scale1,scale2,scale3,k,mype)
l=int(rllat(iglob,jglob))
lp=l+1
- dl2=rllat(iglob,jglob)-float(l)
+ dl2=rllat(iglob,jglob)-real(l,r_kind)
dl1=one-dl2
hwll_loc=cc*(dl1*hwllp(l,n)+dl2*hwllp(lp,n))
scale3(i,j)=one
@@ -6553,7 +6553,7 @@ subroutine isotropic_scales_subdomain_option(scale1,scale2,scale3,k,mype)
l=int(rllat(iglob,jglob))
lp=l+1
- dl2=rllat(iglob,jglob)-float(l)
+ dl2=rllat(iglob,jglob)-real(l,r_kind)
dl1=one-dl2
hwll_loc=cc*(dl1*hwllp(l,nn)+dl2*hwllp(lp,nn))
scale3(i,j)=one
diff --git a/src/gsi/anisofilter_glb.f90 b/src/gsi/anisofilter_glb.f90
index 43e67a3baa..f79b26ab79 100644
--- a/src/gsi/anisofilter_glb.f90
+++ b/src/gsi/anisofilter_glb.f90
@@ -609,7 +609,7 @@ subroutine get_stat_factk(platf,ivar,kvar,factk,rh,dvsst)
l =int(platf)
lp=l+1
- dl2=platf-float(l)
+ dl2=platf-real(l,r_kind)
dl1=one-dl2
l = min(max(1,l ),mlat)
lp= min(max(1,lp),mlat)
@@ -971,7 +971,7 @@ subroutine read_bckgstats_glb(mype)
mcount0=lon2*lat2! It's OK to count buffer points
call mpi_allreduce(pbar4a,pbar4(k),1,mpi_real8,mpi_sum,mpi_comm_world,ierror)
call mpi_allreduce(mcount0,mcount,1,mpi_integer4,mpi_sum,mpi_comm_world,ierror)
- pbar4(k)=pbar4(k)/float(mcount)
+ pbar4(k)=pbar4(k)/real(mcount,r_kind)
end do
psfc015=r015*pbar4(1)
@@ -1160,7 +1160,7 @@ subroutine get_background_glb(mype)
do ilat=1,pf2aP2%nlatf
do ilon=1,pf2aP2%nlonf
- if(((float(ilat)-rnf2)**2+(float(ilon)-rnf2)**2)>=rnf212) then
+ if(((real(ilat,r_kind)-rnf2)**2+(real(ilon,r_kind)-rnf2)**2)>=rnf212) then
p2ilatf(ilat,ilon)=zero
p3ilatf(ilat,ilon)=zero
else
@@ -1611,7 +1611,7 @@ subroutine get_aspect_pt(mype)
cvar=='vp' .or. cvar=='VP' .or. &
cvar=='t' .or. cvar=='T'
- rk1=float(k1-kthres)
+ rk1=real(k1-kthres,r_kind)
fblend=half*(one-tanh(rk1))
!--- zonal patch
@@ -1757,7 +1757,7 @@ subroutine get_theta_corrl_lenghts_glb(mype)
mcount0=lon2*lat2! It's OK to count buffer points
call mpi_allreduce(pbar4a,pbar4(k),1,mpi_real8,mpi_sum,mpi_comm_world,ierror)
call mpi_allreduce(mcount0,mcount,1,mpi_integer4,mpi_sum,mpi_comm_world,ierror)
- pbar4(k)=pbar4(k)/float(mcount)
+ pbar4(k)=pbar4(k)/real(mcount,r_kind)
call w3fa03(pbar4(k),hgt4(k),tbar4(k),thetabar4(k))
end do
@@ -2605,9 +2605,9 @@ subroutine get_aspect_ens(mype)
nt1=max(1,(nens(k)-1))
- s1=maxval(ensv_p0(:,:,k))/float(nt1)
- s2=maxval(ensv_p2(:,:,k))/float(nt1)
- s3=maxval(ensv_p3(:,:,k))/float(nt1)
+ s1=maxval(ensv_p0(:,:,k))/real(nt1,r_kind)
+ s2=maxval(ensv_p2(:,:,k))/real(nt1,r_kind)
+ s3=maxval(ensv_p3(:,:,k))/real(nt1,r_kind)
smax=max(s1,s2,s3)
if ( nkflag(k)==1 ) then
@@ -3729,13 +3729,13 @@ subroutine ens_intpglb_coeff(iref,jref,enscoeff,mype)
xg=rlon+one
yg=rlat+90._r_kind+one
- dxg =xg-float(floor(xg))
- dyg =yg-float(floor(yg))
+ dxg =xg-real(floor(xg),r_kind)
+ dyg =yg-real(floor(yg),r_kind)
dxg1=one-dxg
dyg1=one-dyg
- if (xg >= one .and. xg <= float(jxp) .and. &
- yg >= one .and. yg <= float(iy) ) then
+ if (xg >= one .and. xg <= real(jxp,r_kind) .and. &
+ yg >= one .and. yg <= real(iy,r_kind) ) then
enscoeff(1,i,j)=dxg1*dyg1
enscoeff(2,i,j)=dxg1*dyg
enscoeff(3,i,j)=dxg *dyg1
@@ -3938,7 +3938,7 @@ subroutine ens_uv2psichi(work1,work2)
vor_s = vor_s + grid_vor( 1,ix)
vor_n = vor_n + grid_vor(ny,ix)
end do
- rnlon = one/float(nlon)
+ rnlon = one/real(nlon,r_kind)
div_s = div_s*rnlon
div_n = div_n*rnlon
vor_s = vor_s*rnlon
diff --git a/src/gsi/apply_scaledepwgts.f90 b/src/gsi/apply_scaledepwgts.f90
new file mode 100644
index 0000000000..585711c90b
--- /dev/null
+++ b/src/gsi/apply_scaledepwgts.f90
@@ -0,0 +1,210 @@
+!$$$ program documentation block
+!
+! program history:
+!
+! 2018-03-28 T. Lei and D. Kleist - consoliated and added codes
+! for the scale dependent scale localization scheme
+!
+!$$$ end documentation block
+
+function fwgtofwvlen (rvlft,rvrgt,rcons,rlen,rinput)
+!$$$ subprogram documentation block
+!
+! subprogram: fwgtofwvlen
+!
+! abstract: Calculation of spectral filter functions
+!
+!$$$ end documentation block
+
+ use kinds, only: r_kind
+ implicit none
+
+ real(r_kind),intent(in) :: rvlft,rvrgt,rcons,rlen,rinput
+ real(r_kind) :: fwgtofwvlen
+ real(r_kind) :: rlen1,rtem1,rconshalf
+
+ if(rinput > rvlft .and. rinput < rvrgt) then
+ fwgtofwvlen=rcons
+ else
+ rlen1=rlen/10.0_r_kind ! rlen corresponds to a (-5,5) region
+ rconshalf=0.5_r_kind*rcons
+ rtem1=min(abs(rinput-rvlft),abs(rinput-rvrgt))
+ fwgtofwvlen=rconshalf*(1.0_r_kind+tanh(5.0_r_kind-rtem1/rlen1))
+ endif
+
+end function fwgtofwvlen
+! . . . .
+subroutine init_mult_spc_wgts(jcap_in)
+!$$$ subprogram documentation block
+!
+! subprogram: init_mult_spc_wgts
+!
+!$$$ end documentation block
+
+ use kinds, only: r_kind,i_kind
+ use constants, only: zero,half,one,rearth,pi,tiny_r_kind
+ use mpimod, only: mype
+ use hybrid_ensemble_parameters, only: nsclgrp
+ use hybrid_ensemble_parameters, only: spc_multwgt,spcwgt_params,r_ensloccov4scl
+ implicit none
+
+ integer(i_kind),intent(in ) :: jcap_in
+
+ integer(i_kind) i,l,ks
+ integer(i_kind) ig
+ real(r_kind) :: rwv0,rtem1,rtem2
+ real(r_kind) :: fwgtofwvlen
+ real(r_kind) :: totwvlength
+ real(r_kind),dimension(0:jcap_in,nsclgrp) :: spcwgt
+ logical :: l_sum_spc_weights
+
+ ! Spectral scale decomposition is differernt between SDL-cross and SDL-nocross
+ if( r_ensloccov4scl < tiny_r_kind )then
+ l_sum_spc_weights = .false.
+ else
+ l_sum_spc_weights = .true.
+ end if
+
+ spcwgt(0,1)=one
+ do ig=2,nsclgrp
+ spcwgt(0,ig)=zero
+ end do
+
+
+ rwv0=2.0_r_kind*pi*rearth*0.001_r_kind
+ do i=1,jcap_in
+ totwvlength= rwv0/real(i)
+ rtem1=zero
+ do ig=1,nsclgrp
+ if(ig /= 2) then
+ spcwgt(i,ig)=fwgtofwvlen(spcwgt_params(1,ig),spcwgt_params(2,ig),&
+ spcwgt_params(3,ig),spcwgt_params(4,ig),totwvlength)
+ spcwgt(i,ig)=min(max(spcwgt(i,ig),zero),one)
+ if(l_sum_spc_weights) then
+ rtem1=rtem1+spcwgt(i,ig)
+ else
+ rtem1=rtem1+spcwgt(i,ig)*spcwgt(i,ig)
+ endif
+ endif
+ enddo
+ rtem2 =1.0_r_kind - rtem1
+ if(rtem2 >= zero) then
+
+ if(l_sum_spc_weights) then
+ spcwgt(i,2)=rtem2
+ else
+ spcwgt(i,2)=sqrt(rtem2)
+ endif
+ else
+ if(mype == 0)write(6,*) ' rtem2 < zero ',i,rtem2,(spcwgt(i,ig),ig=1,nsclgrp)
+ spcwgt(i,2)=zero
+ endif
+ enddo
+!! Code borrowed from spvar in splib
+
+ spc_multwgt = zero
+ do ig=1,nsclgrp
+ do i=0,jcap_in
+ ks=2*i
+ spc_multwgt(ks+1,ig)=spcwgt(i,ig)
+ end do
+ do i=0,jcap_in
+ do l=MAX(1,i-jcap_in),MIN(i,jcap_in)
+ ks=l*(2*jcap_in+1-l)+2*i
+ spc_multwgt(ks+1,ig) = spcwgt(i,ig)
+ spc_multwgt(ks+2,ig) = spcwgt(i,ig)
+ end do
+ end do
+ end do
+
+
+ return
+end subroutine init_mult_spc_wgts
+subroutine destroy_mult_spc_wgts
+!$$$ subprogram documentation block
+!
+! subprogram: destroy_mult_spc_wgts
+!
+!$$$ end documentation block
+
+ use hybrid_ensemble_parameters, only: spc_multwgt,spcwgt_params
+ implicit none
+
+ deallocate(spc_multwgt,spcwgt_params)
+
+ return
+end subroutine destroy_mult_spc_wgts
+
+
+subroutine apply_scaledepwgts(m,grd_in,sp_in)
+!
+! Program history log:
+! 2017-03-30 J. Kay, X. Wang - copied from Kleist's apply_scaledepwgts and
+! add the calculation of scale-dependent weighting for mixed resolution ensemble
+! POC: xuguang.wang@ou.edu
+!
+ use constants, only: one
+ use control_vectors, only: control_vector
+ use kinds, only: r_kind,i_kind,r_single
+ use gsi_bundlemod, only: gsi_bundle
+ use general_sub2grid_mod, only: general_sub2grid,general_grid2sub
+ use general_specmod, only: spec_vars
+ use general_sub2grid_mod, only: sub2grid_info
+ use hybrid_ensemble_parameters, only: spc_multwgt,en_perts,nsclgrp,n_ens
+ implicit none
+
+! Declare passed variables
+ integer,intent(in) :: m
+ type(spec_vars),intent (in):: sp_in
+ type(sub2grid_info),intent(in)::grd_in
+
+! Declare local variables
+ integer(i_kind) kk,ig,n,ig2,i,j
+
+ real(r_single),dimension(grd_in%nlat,grd_in%nlon,grd_in%nlevs_alloc,nsclgrp) :: hwork2
+ real(r_kind),dimension(grd_in%nlat,grd_in%nlon) :: work
+ real(r_kind),dimension(sp_in%nc,grd_in%nlevs_alloc):: spc1
+ real(r_kind),dimension(sp_in%nc):: spc2
+
+ do n=1,n_ens
+! Get from subdomains to full grid
+ call general_sub2grid(grd_in,en_perts(n,1,m)%valuesr4(:),hwork2(:,:,:,1))
+
+!$omp parallel do schedule(static,1) private(i,j,kk,work)
+ do kk=1,grd_in%nlevs_loc
+ do j=1,grd_in%nlon
+ do i=1,grd_in%nlat
+ work(i,j)=hwork2(i,j,kk,1)
+ end do
+ end do
+! Transform from physical space to spectral space
+ call general_g2s0(grd_in,sp_in,spc1(1,kk),work)
+
+ end do
+!$omp parallel do schedule(static,1) private(kk,ig,ig2,i,j,work,spc2)
+ do ig2=1,nsclgrp*grd_in%nlevs_loc
+ ig=(ig2-1)/grd_in%nlevs_loc+1
+ kk=ig2-(ig-1)*grd_in%nlevs_loc
+
+ do i=1,sp_in%nc
+ spc2(i)=spc1(i,kk)*spc_multwgt(i,ig)
+ end do
+! Apply spectral weights
+! Transform back to physical space
+ call general_s2g0(grd_in,sp_in,spc2,work)
+
+ do j=1,grd_in%nlon
+ do i=1,grd_in%nlat
+ hwork2(i,j,kk,ig)=work(i,j)
+ end do
+ end do
+ end do
+ do ig=1,nsclgrp
+
+! Transfer work back to subdomains
+ call general_grid2sub(grd_in,hwork2(:,:,:,ig),en_perts(n,ig,m)%valuesr4(:))
+ end do
+ end do
+
+ return
+end subroutine apply_scaledepwgts
diff --git a/src/gsi/atms_spatial_average_mod.f90 b/src/gsi/atms_spatial_average_mod.f90
index dd05faa23e..639bb8c99c 100644
--- a/src/gsi/atms_spatial_average_mod.f90
+++ b/src/gsi/atms_spatial_average_mod.f90
@@ -153,7 +153,7 @@ SUBROUTINE ATMS_Spatial_Average(Num_Obs, NChanl, FOV, Time, BT_InOut, &
Scanline_Back(FOV(I),Scanline(I))=I
END DO
-!$omp parallel do schedule(dynamic,1) private(ichan,iscan,ios,ifov)
+!$omp parallel do schedule(dynamic,1) private(i,ichan,iscan,ios,ifov)
DO IChan=1,nchanl
err(ichan)=0
@@ -841,7 +841,7 @@ SUBROUTINE SFFTCB( X, N, M )
END DO
J = J + K
104 CONTINUE
- XT = 1.0_r_kind / FLOAT( N )
+ XT = 1.0_r_kind / real( N,r_kind )
DO 99, I = 1, N
X(I) = XT * X(I)
99 CONTINUE
diff --git a/src/gsi/balmod.f90 b/src/gsi/balmod.f90
index 1b9fa9030b..96181864a1 100644
--- a/src/gsi/balmod.f90
+++ b/src/gsi/balmod.f90
@@ -443,7 +443,7 @@ subroutine prebal_reg(cwcoveqqcov)
do i=1,lat2
l=int(rllat1(i,j))
l2=min0(l+1,llmax)
- dl2=rllat1(i,j)-float(l)
+ dl2=rllat1(i,j)-real(l,r_kind)
dl1=one-dl2
bvk(i,j,k)=dl1*bvi(l,k)+dl2*bvi(l2,k)
end do
@@ -465,7 +465,7 @@ subroutine prebal_reg(cwcoveqqcov)
do i=1,lat2
l=int(rllat1(i,j))
l2=min0(l+1,llmax)
- dl2=rllat1(i,j)-float(l)
+ dl2=rllat1(i,j)-real(l,r_kind)
dl1=one-dl2
agvk(i,j,m,k)=dl1*agvi(l,m,k)+dl2*agvi(l2,m,k)
end do
@@ -477,7 +477,7 @@ subroutine prebal_reg(cwcoveqqcov)
do i=1,lat2
l=int(rllat1(i,j))
l2=min0(l+1,llmax)
- dl2=rllat1(i,j)-float(l)
+ dl2=rllat1(i,j)-real(l,r_kind)
dl1=one-dl2
wgvk(i,j,k)=dl1*wgvi(l,k)+dl2*wgvi(l2,k)
end do
@@ -689,13 +689,7 @@ subroutine balance(t,p,st,vp,fpsproj,fut2ps)
!! Strong balance constraint
!! Pass uvflag=.false.
- if(lsqrtb) then
- call strong_bk(st,vp,p,t,.false.)
- else
- if(tlnmc_option==1 .or. tlnmc_option==4) call strong_bk(st,vp,p,t,.false.)
- endif
-
-
+ if(lsqrtb .or. tlnmc_option==1 .or. tlnmc_option==4) call strong_bk(st,vp,p,t,.false.)
return
end subroutine balance
@@ -777,11 +771,7 @@ subroutine tbalance(t,p,st,vp,fpsproj,fut2ps)
! Adjoint of strong balance constraint
! pass uvflag=.false.
- if(lsqrtb) then
- call strong_bk_ad(st,vp,p,t,.false.)
- else
- if(tlnmc_option==1 .or. tlnmc_option==4) call strong_bk_ad(st,vp,p,t,.false.)
- endif
+ if(lsqrtb .or. tlnmc_option==1 .or. tlnmc_option==4) call strong_bk_ad(st,vp,p,t,.false.)
! REGIONAL BRANCH
if (regional) then
@@ -972,7 +962,7 @@ subroutine locatelat_reg(mype)
do j=1,nlon
do i=1,nlat
if(region_lat(i,j)>=clat_avn(mlat))then
- rllat(i,j)=float(mlat)
+ rllat(i,j)=real(mlat,r_kind)
llmax=max0(mlat,llmax)
llmin=min0(mlat,llmin)
else if(region_lat(i,j)=clat_avn(m)).and. &
(region_lat(i,j)0)then
allocate(alv(llmin:llmax,ndeg,nsig,nc3d), &
dssv(lat2,lon2,nsig,nc3d))
diff --git a/src/gsi/bicg.f90 b/src/gsi/bicg.f90
index 6eb2f78905..d7ac743d8f 100644
--- a/src/gsi/bicg.f90
+++ b/src/gsi/bicg.f90
@@ -30,7 +30,7 @@ subroutine bicg()
use kinds, only: r_kind,i_kind,r_quad
use gsi_4dvar, only: l4dvar, &
- ladtest, lgrtest, lanczosave, ltcost, nwrvecs
+ ladtest, lgrtest, lanczosave, ltcost, nwrvecs, lsqrtb
use jfunc, only: jiter,miter,niter,xhatsave,yhatsave,jiterstart
use constants, only: zero,tiny_r_kind
use mpimod, only: mype
@@ -39,6 +39,7 @@ subroutine bicg()
use obsmod, only: lsaveobsens,l_do_adjoint
use adjtest, only: adtest
use grdtest, only: grtest
+use gsi_bundlemod, only : gsi_bundlegetpointer
use control_vectors, only: control_vector
use control_vectors, only: allocate_cv,deallocate_cv,write_cv,inquire_cv
use control_vectors, only: dot_product,assignment(=)
@@ -89,6 +90,13 @@ subroutine bicg()
call allocate_cv(gradf)
call allocate_cv(grads)
+if(l_hyb_ens .and. .not. aniso_a_en) then
+ if (lsqrtb) then
+ write(6,*)'l_hyb_ens: not for use with lsqrtb'
+ call stop2(317)
+ end if
+end if
+
! Get initial cost function and gradient
nprt=2
diff --git a/src/gsi/bicglanczos.F90 b/src/gsi/bicglanczos.F90
index 1914b0214d..13525e38cb 100755
--- a/src/gsi/bicglanczos.F90
+++ b/src/gsi/bicglanczos.F90
@@ -57,13 +57,14 @@ module bicglanczos
use constants, only : zero, one, half,two, zero_quad,tiny_r_kind
use timermod , only : timer_ini, timer_fnl
use lanczos , only : save_precond
-use gsi_4dvar, only : iorthomax
+use gsi_4dvar, only : iorthomax,lsqrtb
use control_vectors, only: control_vector
use control_vectors, only: allocate_cv,deallocate_cv,inquire_cv
use control_vectors, only: read_cv,write_cv
use control_vectors, only: dot_product,assignment(=)
use gsi_bundlemod, only: gsi_bundle
use gsi_bundlemod, only: assignment(=)
+use gsi_bundlemod, only : gsi_bundlegetpointer
use mpimod , only : mpi_comm_world
use mpimod, only: mype
use jfunc , only : iter, jiter
@@ -248,7 +249,13 @@ subroutine pcglanczos(xhat,yhat,pcost,gradx,grady,preduc,kmaxit,lsavevecs)
if(nprt>=1.and.ltcost_) call allocate_cv(gradf)
call allocate_cv(dirw)
-!--- 'zeta' is an upper bound on the relative error of the gradient.
+if(l_hyb_ens .and. .not. aniso_a_en) then
+ if (lsqrtb) then
+ write(6,*)'l_hyb_ens: not for use with lsqrtb'
+ call stop2(317)
+ end if
+end if
+ !--- 'zeta' is an upper bound on the relative error of the gradient.
zeta = 1.0e-4_r_kind
zreqrd = preduc
diff --git a/src/gsi/bkerror.f90 b/src/gsi/bkerror.f90
index b3a0140691..7eb83b09d6 100644
--- a/src/gsi/bkerror.f90
+++ b/src/gsi/bkerror.f90
@@ -71,7 +71,6 @@ subroutine bkerror(grady)
! Declare local variables
integer(i_kind) i,ii
- integer(i_kind) i_t,i_p,i_st,i_vp
integer(i_kind) ipnts(4),istatus
! integer(i_kind) nval_lenz,ndim2d
real(r_kind),pointer,dimension(:,:,:):: p_t =>NULL()
@@ -97,11 +96,7 @@ subroutine bkerror(grady)
! Only need to get pointer for ii=1 - all other are the same
call gsi_bundlegetpointer ( grady%step(1), (/'t ','sf','vp','ps'/), &
ipnts, istatus )
- i_t = ipnts(1)
- i_st = ipnts(2)
- i_vp = ipnts(3)
- i_p = ipnts(4)
- dobal = i_t>0.and.i_p>0.and.i_st>0.and.i_vp>0
+ dobal = ipnts(1)>0 .and. ipnts(2)>0 .and. ipnts(3)>0 .and. ipnts(4)>0
! if ensemble run, multiply by sqrt_beta_s
if(l_hyb_ens) call sqrt_beta_s_mult(grady)
diff --git a/src/gsi/bkgvar_rewgt.f90 b/src/gsi/bkgvar_rewgt.f90
index ca82882af3..c463723206 100644
--- a/src/gsi/bkgvar_rewgt.f90
+++ b/src/gsi/bkgvar_rewgt.f90
@@ -99,7 +99,7 @@ subroutine bkgvar_rewgt(sfvar,vpvar,tvar,psvar,mype)
balt =zero ; bald =zero ; balps =zero
! Set count to number of global grid points in quad precision
- fcount = float(nlat)*float(nlon)
+ fcount = real(nlat*nlon,r_kind)
! Set parameter for communication
mm1=mype+1
diff --git a/src/gsi/buddycheck_mod.f90 b/src/gsi/buddycheck_mod.f90
index ae4a29cc63..9c58fd0a44 100644
--- a/src/gsi/buddycheck_mod.f90
+++ b/src/gsi/buddycheck_mod.f90
@@ -200,7 +200,7 @@ subroutine buddy_check_t(is,data,luse,mype,nele,nobs,muse,buddyuse)
end if
- rsig=float(nsig)
+ rsig=real(nsig,r_kind)
mm1=mype+1
!initialize buddyuse to 1, start by assuming all obs are good!
diff --git a/src/gsi/cads.f90 b/src/gsi/cads.f90
new file mode 100644
index 0000000000..6d7e584ef1
--- /dev/null
+++ b/src/gsi/cads.f90
@@ -0,0 +1,2230 @@
+module cads
+!$$$ module documentation block
+!
+! module: cads
+! prgmmr: Jung
+!
+! abstract: module containing subroutines for the cloud and aerosol detection software
+!
+! program history log:
+!
+!
+!
+! subroutines included:
+!
+!
+! remarks: variable definitions
+!
+!
+!$$$ end documentation block
+
+
+ use kinds, only: i_kind, r_kind
+ implicit none
+ save
+
+! set default to private
+ private
+! set routines to public
+ public :: cloud_aerosol_detection
+ public :: cads_setup_cloud
+ public :: Cloud_Detect_Type
+ public :: cads_imager_calc
+
+ public :: M__Sensor,N__Num_Bands,N__GradChkInterval,N__Band_Size,N__Bands,N__Window_Width, &
+ N__Window_Bounds,R__BT_Threshold,R__Grad_Threshold,R__Window_Grad_Threshold, L__Do_Quick_Exit, &
+ L__Do_CrossBand, N__BandToUse,L__Do_Imager_Cloud_Detection, N__Num_Imager_Chans, &
+ N__Num_Imager_Clusters,N__Imager_Chans,R__Stddev_Threshold,R__Coverage_Threshold, &
+ R__FG_Departure_Threshold
+
+ INTEGER(i_kind) :: M__Sensor ! Unique ID for sensor
+ INTEGER(i_kind) :: N__Num_Bands ! Number of channel bands
+ INTEGER(i_kind), POINTER :: N__GradChkInterval(:) ! Window width used in gradient calculation
+ INTEGER(i_kind), POINTER :: N__Band_Size(:) ! Number of channels in each band
+ INTEGER(i_kind), POINTER :: N__Bands(:,:) ! Channel lists
+ INTEGER(i_kind), POINTER :: N__Window_Width(:) ! Smoothing filter window widths per band
+ INTEGER(i_kind), POINTER :: N__Window_Bounds(:,:) ! Channels in the spectral window gradient check
+ INTEGER(i_kind), POINTER :: N__BandToUse(:) ! Band number assignment for each channel
+ LOGICAL :: L__Do_Quick_Exit ! On/off switch for the Quick Exit scenario
+ LOGICAL :: L__Do_CrossBand ! On/off switch for the cross-band method
+ REAL(r_kind), POINTER :: R__BT_Threshold(:) ! BT threshold for cloud contamination
+ REAL(r_kind), POINTER :: R__Grad_Threshold(:) ! Gradient threshold for cloud contamination
+ REAL(r_kind), POINTER :: R__Window_Grad_Threshold(:) ! Threshold for window gradient check in QE
+
+ LOGICAL :: L__Do_Imager_Cloud_Detection ! On/off switch for the imager cloud detection
+ INTEGER(i_kind) :: N__Num_Imager_Chans ! No. of imager channels
+ INTEGER(i_kind) :: N__Num_Imager_Clusters ! No. of clusters to be expected
+ INTEGER(i_kind),POINTER :: N__Imager_Chans(:) ! List of imager channels
+ REAL(r_kind),POINTER :: R__Stddev_Threshold(:) ! St. Dev. threshold, one for each imager channel
+ REAL(r_kind) :: R__Coverage_Threshold ! Threshold for fractional coverage of a cluster
+ REAL(r_kind) :: R__FG_Departure_Threshold ! Threshold for imager FG departure
+
+
+! set passed variables to public
+
+! This software was developed within the context of the EUMETSAT
+! Satellite Application Facility on Numerical Weather Prediction
+! (NWP SAF), under the Cooperation Agreement dated 7 December 2016,
+! between EUMETSAT and the Met Office, UK, by one or more partners
+! within the NWP SAF. The partners in the NWP SAF are the Met
+! Office, ECMWF, DWD and MeteoFrance.
+!
+! Copyright 2020, EUMETSAT, All Rights Reserved.
+
+! * CADS_Module *
+! A. Collard ECMWF 01/02/06
+
+! * PURPOSE *
+! -----------
+! Sets up structures to be used in processing of advanced IR sounders.
+
+! * MODIFICATIONS *
+! -----------------
+! 01/02/06 A.Collard 1.0 Original export version.
+! 17/11/09 R.Eresmaa 1.1 Include parameters of the Quick Exit /
+! long-wave window gradient check.
+! 11/11/11 R.Eresmaa 1.2 Add processing capability for CrIS.
+! 03/12/13 R.Eresmaa 2.0 Add imager-assisted cloud detection.
+! 10/11/15 R.Eresmaa 2.2 Changed instrument ID naming convention.
+! Changed aerosol detection parameters.
+! 20/12/16 R.Eresmaa 2.3 Remove aerosol detection parameters.
+! 05/02/19 R.Eresmaa 2.4 Explicit KIND specifications.
+! 16/04/20 R.Eresmaa 3.0 Combine cloud and aerosol detection, rename.
+! Include aerosol type recognition.
+! Include land sensitivity parameters.
+! Include trace gas detection. Rename.
+
+
+ INTEGER(i_kind), PARAMETER :: INST_ID_AIRS = 11
+ INTEGER(i_kind), PARAMETER :: INST_ID_IASI = 16
+ INTEGER(i_kind), PARAMETER :: INST_ID_CRIS = 27
+ INTEGER(i_kind), PARAMETER :: INST_ID_IRS = 57
+ INTEGER(i_kind), PARAMETER :: INST_ID_IASING = 59
+ INTEGER(i_kind), PARAMETER :: INST_ID_IKFS2 = 94
+ INTEGER(i_kind), PARAMETER :: INST_ID_HIRAS = 97
+ INTEGER(i_kind), PARAMETER :: INST_ID_GIIRS = 98
+
+ INTEGER(i_kind), PARAMETER :: JP__MIN_SENSOR_INDEX = INST_ID_AIRS
+ INTEGER(i_kind), PARAMETER :: JP__MAX_SENSOR_INDEX = INST_ID_GIIRS
+
+ TYPE Aerosol_Detect_Type
+ INTEGER(i_kind) :: M__Sensor ! Unique ID for sensor
+ INTEGER(i_kind) :: N__Num_Aerosol_Tests ! Number of aerosol detection tests
+ INTEGER(i_kind), POINTER :: N__Num_Regression(:) ! Number of conversion coefficients for AOD
+ INTEGER(i_kind), POINTER :: N__Num_Aerosol_Chans(:) ! Number of aerosol detection channels
+ INTEGER(i_kind), POINTER :: N__Aerosol_Chans(:,:) ! List of aerosol detection channels
+ INTEGER(i_kind) :: N__Mean_Aerosol_Chans ! Boxcar averaging window width
+ REAL(r_kind), POINTER :: R__Aerosol_TBD(:,:) ! Aerosol detection thresholds
+ REAL(r_kind), POINTER :: R__coef_AOD(:,:) ! Coefficients for conversion to AOD
+ REAL(r_kind) :: R__Rank_Thres_Coeff(3) ! Coefficients to restrict rejections to affected channels
+ REAL(r_kind) :: R__Unclassified_Thres ! Rejection threshold for unclassified aerosol
+ REAL(r_kind) :: R__Land_Fraction_Thres ! Threshold for land fraction in FOV
+ END TYPE Aerosol_Detect_Type
+
+ TYPE Cloud_Detect_Type
+ INTEGER(i_kind) :: M__Sensor ! Unique ID for sensor
+ INTEGER(i_kind) :: N__Num_Bands ! Number of channel bands
+ INTEGER(i_kind), POINTER :: N__GradChkInterval(:) ! Window width used in gradient calculation
+ INTEGER(i_kind), POINTER :: N__Band_Size(:) ! Number of channels in each band
+ INTEGER(i_kind), POINTER :: N__Bands(:,:) ! Channel lists
+ INTEGER(i_kind), POINTER :: N__Window_Width(:) ! Smoothing filter window widths per band
+ INTEGER(i_kind), POINTER :: N__Window_Bounds(:,:) ! Channels in the spectral window gradient check
+ INTEGER(i_kind), POINTER :: N__BandToUse(:) ! Band number assignment for each channel
+ LOGICAL :: L__Do_Quick_Exit ! On/off switch for the Quick Exit scenario
+ LOGICAL :: L__Do_CrossBand ! On/off switch for the cross-band method
+ REAL(r_kind), POINTER :: R__BT_Threshold(:) ! BT threshold for cloud contamination
+ REAL(r_kind), POINTER :: R__Grad_Threshold(:) ! Gradient threshold for cloud contamination
+ REAL(r_kind), POINTER :: R__Window_Grad_Threshold(:) ! Threshold for window gradient check in QE
+
+ LOGICAL :: L__Do_Imager_Cloud_Detection ! On/off switch for the imager cloud detection
+ INTEGER(i_kind) :: N__Num_Imager_Chans ! No. of imager channels
+ INTEGER(i_kind) :: N__Num_Imager_Clusters ! No. of clusters to be expected
+ INTEGER(i_kind),POINTER :: N__Imager_Chans(:) ! List of imager channels
+ REAL(r_kind),POINTER :: R__Stddev_Threshold(:) ! St. Dev. threshold, one for each imager channel
+ REAL(r_kind) :: R__Coverage_Threshold ! Threshold for fractional coverage of a cluster
+ REAL(r_kind) :: R__FG_Departure_Threshold ! Threshold for imager FG departure
+ END TYPE Cloud_Detect_Type
+
+ TYPE Land_Sensitivity_Type
+ INTEGER(r_kind) :: M__Sensor ! Unique ID for sensor
+ REAL(r_kind) :: R__Land_Fraction_Thres ! Threshold on land fraction
+ REAl(r_kind) :: R__Level_Thres ! Threshold on normalized channel height assignment
+ END TYPE Land_Sensitivity_Type
+
+ TYPE Trace_Gas_Detect_Type
+ INTEGER(i_kind) :: M__Sensor ! Unique ID for sensor
+ INTEGER(i_kind) :: N__Num_Trace_Gas_Checks ! Number of trace gases to be checked
+ INTEGER(i_kind),POINTER :: N__Num_Tracer_Channels(:) ! Number of gas-sensitive channels
+ INTEGER(i_kind),POINTER :: N__Tracer_Channels(:,:) ! Gas-sensitive channels
+ INTEGER(i_kind),POINTER :: N__Num_Control_Channels(:) ! Number of control channels
+ INTEGER(i_kind),POINTER :: N__Control_Channels(:,:) ! Control channels
+ INTEGER(i_kind),POINTER :: N__Num_Flagged_Channels(:) ! Number of affected channels
+ INTEGER(i_kind),POINTER :: N__Flagged_Channels(:,:) ! Affected channels
+ REAL(r_kind),POINTER :: R__D_Obs_Threshold(:) ! Observed Tb difference threshold
+ REAL(r_kind),POINTER :: R__D_Dep_Threshold(:) ! Departure difference threshold
+ END TYPE Trace_Gas_Detect_Type
+
+
+ TYPE(Aerosol_Detect_Type) :: &
+ S__CADS_Setup_Aerosol(JP__Min_Sensor_Index:JP__Max_Sensor_Index)
+
+ TYPE(Cloud_Detect_Type) :: &
+ S__CADS_Setup_Cloud(JP__Min_Sensor_Index:JP__Max_Sensor_Index)
+
+ TYPE(Land_Sensitivity_Type) :: &
+ S__CADS_Setup_Land(JP__Min_Sensor_Index:JP__Max_Sensor_Index)
+
+ TYPE(Trace_Gas_Detect_Type) :: &
+ S__CADS_Setup_Trace_Gas(JP__Min_Sensor_Index:JP__Max_Sensor_Index)
+
+
+contains
+
+SUBROUTINE CADS_Abort(String)
+
+! This software was developed within the context of the EUMETSAT
+! Satellite Application Facility on Numerical Weather Prediction
+! (NWP SAF), under the Cooperation Agreement dated 7 December 2016,
+! between EUMETSAT and the Met Office, UK, by one or more partners
+! within the NWP SAF. The partners in the NWP SAF are the Met
+! Office, ECMWF, DWD and MeteoFrance.
+!
+! Copyright 2020, EUMETSAT, All Rights Reserved.
+
+! *CADS_Abort*
+! R. Eresmaa ECMWF 16/04/20
+
+! * PURPOSE *
+! -----------
+! Controlled abortion of running CADS when facing exceptions such as
+! necessary input files missing or they are corrupt.
+
+! * INTERFACE *
+! -------------
+! *CALL* * CADS_Abort()* from
+! CADS_Main, CADS_Setup_Aerosol, CADS_Setup_Cloud,
+! CADS_Setup_Land_Sensitivity, or CADS_Setup_Trace_Gas.
+
+ IMPLICIT NONE
+ CHARACTER(LEN=*) :: String
+
+ WRITE(*,*) String
+ STOP
+
+END SUBROUTINE CADS_Abort
+
+subroutine cloud_aerosol_detection( I__Sensor_ID, I__Num_Chans, I__Chan_ID, &
+ I__Min_Level, I__Max_Level, Z__BT_Obser, Z__BT_Model, Z__Chan_Height, K__Chan_ID_Imager, &
+ Z__Cluster_Fraction, Z__BT_in_Cluster, Z__BT_Overall_SDev, Z__BT_Model_Imager, &
+ I__Flag_Cloud, Z__Cloud_Level )
+
+!$$$ subprogram documentation block
+! . . .
+! subprogram: cloud_aerosol_detection determine clear/cloudy profiles from hyperspectral IR instruments
+!
+! prgmmr: jung org: cimss date: 2022-10-17
+!
+! abstract: determine if a profile is clear/cloudy. If cloudy, determine which channels are affected
+! This subroutine is designed for infrared hyperspectral sounders. Current code supports AIRS, IASI and CrIS.a
+! This subroutine is based on the Cloud and Aerosol Detection Software Version 3 developed within the context
+! of the EUMETSAT and Met Office, UK, by one or more partners within the Numerical Weather Predicion's
+! Satellite Application Facilities. A version of this code is operational at ECMWF.
+! COPYRIGHT 2020, EUMETSAT, ALL RIGHTS RESERVED.
+!
+! program history log:
+! 2022-10-17 jung Initial coding
+!
+! input argument list:
+! I_Sensor_ID - internal sensor identification.
+! I__Num_Chans - number of channels per obs
+! I__Chan_ID - array of actual channel numbers
+! Z__Longitude - FOV longitude
+! Z__Latitude - FOV latitude
+! Z__Land_Fraction - FOV land fraction
+! I__Min_Level - model tropopause height (start of cloud detection)
+! I__Max_Level - model top of boundary layer ( stop of cloud detection)
+! Z__BT_Obser - observaton brightness temperature
+! Z__BT_Model - model derived brightness temperature
+! Z__Chan_Height - model derived height where an opaque cloud influences the radiance.
+! also used to re-organize channels
+! Z__Cloud_Level - Cloud height assignment
+!
+! output argument list:
+! icloud_layer - model layer where cloud is detected
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+ use kinds, only: i_kind, r_kind
+ implicit none
+
+ integer(i_kind), intent(in ) :: I__Sensor_ID
+ integer(i_kind), intent(in ) :: I__Num_Chans
+ integer(i_kind),dimension(I__Num_Chans),intent(in ) :: I__Chan_ID
+ integer(i_kind), intent(in ) :: I__Min_Level !tropopause pressure
+ integer(i_kind), intent(in ) :: I__Max_Level !boundary layer pressure
+ real(r_kind), intent(in ) :: Z__BT_Obser(:) !Observation BT
+ real(r_kind), intent(in ) :: Z__BT_Model(:) !Model derived BT
+ real(r_kind), intent(in ) :: Z__Chan_Height(:) !Channel height assignmenta
+ integer(i_kind), intent(in ) :: K__Chan_ID_Imager(:) ! imager channel numbers
+ real(r_kind), intent(in ) :: Z__Cluster_Fraction(:)
+ real(r_kind), intent(in ) :: Z__BT_in_Cluster(:,:)
+ real(r_kind), intent(in ) :: Z__BT_Overall_SDev(:)
+ real(r_kind), intent(in ) :: Z__BT_Model_Imager(:)
+ real(r_kind), intent( out) :: Z__Cloud_Level ! cloud height assignment
+ integer(i_kind),dimension(I__Num_Chans),intent( out) :: I__Flag_Cloud ! cloud use flag
+
+! Interim prodcts
+
+! Diagnostics: percentages of positive detections
+! Input/Output file management
+
+ N__Num_Imager_Chans = S__CADS_Setup_Cloud(I__Sensor_ID) % N__Num_Imager_Chans
+ N__Num_Imager_Clusters = S__CADS_Setup_Cloud(I__Sensor_ID) % N__Num_Imager_Clusters
+
+ CALL CADS_Detect_Cloud( I__Sensor_ID, I__Num_Chans, I__Chan_ID,I__Min_Level, I__Max_Level, N__Num_Imager_Chans, &
+ K__Chan_ID_Imager, N__Num_Imager_Clusters, I__Flag_Cloud, Z__BT_Obser, Z__BT_Model, Z__Chan_Height, &
+ Z__Cluster_Fraction, Z__BT_in_Cluster, Z__BT_Overall_SDev, Z__BT_Model_Imager, Z__Cloud_Level )
+
+end subroutine cloud_aerosol_detection
+
+SUBROUTINE CADS_Setup_Cloud
+
+! This software was developed within the context of the EUMETSAT
+! Satellite Application Facility on Numerical Weather Prediction
+! (NWP SAF), under the Cooperation Agreement dated 7 December 2016,
+! between EUMETSAT and the Met Office, UK, by one or more partners
+! within the NWP SAF. The partners in the NWP SAF are the Met
+! Office, ECMWF, DWD and Meteo France.
+!
+! Copyright 2020, EUMETSAT, All Rights Reserved.
+
+
+! * Cloud detection setup *
+! A. Collard ECMWF 01/02/06
+
+! * PURPOSE *
+! -----------
+! Initialise cloud detection parameters for advanced infrared sounders.
+
+! * INTERFACE *
+! -------------
+! CADS_Setup_Cloud is called from CADS_Main.
+
+! * METHOD *
+! ----------
+! Default values are assigned to the cloud detections setup structure.
+
+! MODIFICATIONS
+! -------------
+! 01/02/06 A.Collard 1.0 Original code.
+! 19/10/06 A.Collard 1.1 Use IASI 300 Subset Channels.
+! 17/11/09 R.Eresmaa 1.2 Use IASI 366 Subset Channels.
+! Include parameters of the Quick Exit /
+! long-wave window gradient check parameters.
+! 11/11/11 R.Eresmaa 1.3 Default channel list for AIRS bands 3-5
+! modified.
+! Processing capability for CrIS added
+! assuming a selection of 320 channels.
+! 03/12/13 R,Eresmaa 2.0 Imager-assisted cloud detection added for
+! IASI.
+! Updated setup for CrIS.
+! 19/01/15 R.Eresmaa 2.1 Remove unused variable specifications and
+! switch aerosol detection on by default for
+! AIRS and IASI.
+! 10/11/15 R.Eresmaa 2.2 Changed instrument ID naming convention.
+! Changed parameters of aerosol detection.
+! 20/12/16 R.Eresmaa 2.3 Remove settings for aerosol detection.
+! 05/02/19 R.Eresmaa 2.4 Explicit KIND specifications.
+! Add HIRAS, GIIRS (IASING + IRS added earlier)
+! 16/04/20 R.Eresmaa 3.0 Rename, tidy up.
+
+ use kinds, only: i_kind, r_kind
+ use gsi_io, only: verbose
+ IMPLICIT NONE
+
+! Local variables
+
+ CHARACTER(LEN=6) :: CL__InstrumentName
+ CHARACTER(LEN=20) :: CL__Cloud_Detection_File
+
+ INTEGER(i_kind) :: J, J__Sensor ! Loop variables
+ INTEGER(i_kind) :: INIU1, IOS
+
+!-----------------------
+! Namelist variables
+!-----------------------
+
+! N.B. Max_Bands must be greater than 5
+ INTEGER(i_kind), PARAMETER :: JP__Max_Bands = 8
+ INTEGER(i_kind), PARAMETER :: JP__Max_Channels = 8461
+
+ INTEGER(i_kind) :: M__Sensor
+ INTEGER(i_kind) :: N__Num_Bands
+ INTEGER(i_kind) :: N__GradChkInterval(JP__Max_Bands)
+ INTEGER(i_kind) :: N__Band_Size(JP__Max_Bands)
+ INTEGER(i_kind) :: N__Bands(JP__Max_Channels,JP__Max_Bands)
+ INTEGER(i_kind) :: N__Window_Width(JP__Max_Bands)
+ INTEGER(i_kind) :: N__Window_Bounds(JP__Max_Bands,2)
+ REAL(r_kind) :: R__BT_Threshold(JP__Max_Bands)
+ REAL(r_kind) :: R__Grad_Threshold(JP__Max_Bands)
+ REAL(r_kind) :: R__Window_Grad_Threshold(JP__Max_Bands)
+ LOGICAL :: L__Do_Quick_Exit
+ LOGICAL :: L__Do_CrossBand
+ INTEGER(i_kind) :: N__BandToUse(JP__Max_Bands)
+
+! Imager-based cloud detection
+ LOGICAL :: L__Do_Imager_Cloud_Detection
+ INTEGER(i_kind) :: N__Num_Imager_Chans
+ INTEGER(i_kind) :: N__Num_Imager_Clusters
+ INTEGER(i_kind) :: N__Imager_Chans(JP__Max_Bands)
+ REAL(r_kind) :: R__Stddev_Threshold(JP__Max_Bands)
+ REAL(r_kind) :: R__Coverage_Threshold
+ REAL(r_kind) :: R__FG_Departure_Threshold
+
+! Namelist
+ NAMELIST / Cloud_Detect_Coeffs / M__Sensor, N__Num_Bands, &
+ N__Band_Size, N__Bands, N__Window_Width, N__Window_Bounds, &
+ N__GradChkInterval, R__BT_Threshold, R__Grad_Threshold, &
+ R__Window_Grad_Threshold, L__Do_Quick_Exit, &
+ L__Do_CrossBand, N__BandToUse, &
+ L__Do_Imager_Cloud_Detection, N__Num_Imager_Chans, &
+ N__Num_Imager_Clusters, N__Imager_Chans, &
+ R__Stddev_Threshold, R__Coverage_Threshold, &
+ R__FG_Departure_Threshold
+
+!============================================================================
+! Loop through sensors setting up cloud detection
+!============================================================================
+
+ SensorLoop : DO J__Sensor = JP__Min_Sensor_Index, JP__Max_Sensor_Index
+
+! SELECT CASE (I__Sensor_ID)
+ SELECT CASE (J__Sensor)
+
+ CASE(INST_ID_AIRS)
+ !====================
+ ! Set up AIRS
+ !====================
+
+ CL__InstrumentName='AIRS'
+ CL__Cloud_Detection_File = 'AIRS_CLDDET.NL'
+
+ N__Num_Bands = 5
+
+ N__Band_Size(:) = 0
+ N__Band_Size(1:N__Num_Bands) =(/138, 36, 54, 23, 65 /)
+
+ N__Bands(:,:)= 0
+
+ N__Bands(1:N__Band_Size(1),1) = &
+ (/ 1, 6, 7, 10, 11, 15, 16, 17, 20, 21, &
+ 22, 24, 27, 28, 30, 36, 39, 40, 42, 51, &
+ 52, 54, 55, 56, 59, 62, 63, 68, 69, 71, &
+ 72, 73, 74, 75, 76, 77, 78, 79, 80, 82, &
+ 83, 84, 86, 92, 93, 98, 99, 101, 104, 105, &
+ 108, 110, 111, 113, 116, 117, 123, 124, 128, 129, &
+ 138, 139, 144, 145, 150, 151, 156, 157, 159, 162, &
+ 165, 168, 169, 170, 172, 173, 174, 175, 177, 179, &
+ 180, 182, 185, 186, 190, 192, 193, 198, 201, 204, &
+ 207, 210, 213, 215, 216, 218, 221, 224, 226, 227, &
+ 232, 239, 248, 250, 251, 252, 253, 256, 257, 261, &
+ 262, 267, 272, 295, 299, 305, 308, 309, 310, &
+ 318, 321, 333, 338, 355, 362, 375, 475, &
+ 484, 497, 528, 587, 672, 787, 791, 843, 870, 914, &
+ 950 /)
+
+ N__Bands(1:N__Band_Size(2),2) = &
+ (/ 1003, 1012, 1019, 1024, 1030, 1038, 1048, 1069, 1079, 1082, &
+ 1083, 1088, 1090, 1092, 1095, 1104, 1111, 1115, 1116, 1119, &
+ 1120, 1123, 1130, 1138, 1142, 1178, 1199, 1206, 1221, 1237, &
+ 1252, 1260, 1263, 1266, 1278, 1285 /)
+
+ N__Bands(1:N__Band_Size(3),3) = &
+ (/ 1290, 1301, 1304, 1329, 1371, 1382, 1415, 1424, 1449, 1455, &
+ 1466, 1471, 1477, 1479, 1488, 1500, 1519, 1520, 1538, 1545, &
+ 1565, 1574, 1583, 1593, 1614, 1627, 1636, 1644, 1652, 1669, &
+ 1674, 1681, 1694, 1708, 1717, 1723, 1740, 1748, 1751, 1756, &
+ 1763, 1766, 1771, 1777, 1780, 1783, 1794, 1800, 1803, 1806, &
+ 1812, 1826, 1843, 1852 /)
+
+ N__Bands(1:N__Band_Size(4),4) = &
+ (/ 1865, 1866, 1867, 1868, 1869, 1872, 1873, 1875, 1876, 1877, &
+ 1881, 1882, 1883, 1884, 1897, 1901, 1911, 1917, 1918, 1921, &
+ 1923, 1924, 1928 /)
+
+ N__Bands(1:N__Band_Size(5),5) = &
+ (/ 1937, 1938, 1939, 1941, 1946, 1947, 1948, 1958, 1971, 1973, &
+ 1988, 1995, 2084, 2085, 2097, 2098, 2099, 2100, 2101, 2103, &
+ 2104, 2106, 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2114, &
+ 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2128, &
+ 2134, 2141, 2145, 2149, 2153, 2164, 2189, 2197, 2209, 2226, &
+ 2234, 2280, 2318, 2321, 2325, 2328, 2333, 2339, 2348, 2353, &
+ 2355, 2363, 2370, 2371, 2377 /)
+
+ N__GradChkInterval(:) = 0
+ N__GradChkInterval(1:N__Num_Bands) = (/ 5,5,5,5,5 /)
+
+ N__Window_Width(:) = 0
+ N__Window_Width(1:N__Num_Bands) = (/ 14,6,8,5,8 /)
+
+ N__Window_Bounds(:,:) = 0
+ N__Window_Bounds(1,1) = 475
+ N__Window_Bounds(1,2) = 950
+
+ R__BT_Threshold(:) = 0.0_r_kind
+ R__BT_Threshold(1:N__Num_Bands) = (/ 0.43_r_kind, 0.5_r_kind, 0.5_r_kind, 0.5_r_kind, 0.5_r_kind/)
+
+ R__Grad_Threshold(:) = 0.0_r_kind
+ R__Grad_Threshold(1:N__Num_Bands) = (/ 0.02_r_kind, 0.02_r_kind, 0.02_r_kind, 0.02_r_kind, 0.02_r_kind /)
+
+ R__Window_Grad_Threshold(:) = 0.0_r_kind
+ R__Window_Grad_Threshold(1) = 0.4_r_kind
+
+ L__Do_Quick_Exit = .TRUE.
+
+
+ ! This is cross-band:
+
+ L__Do_CrossBand = .TRUE.
+
+ N__BandToUse(:) = 0
+ N__BandToUse(1:N__Num_Bands) = (/ 1,1,1,4,1 /)
+
+
+ ! This is the setup for imager cloud detection
+
+ L__Do_Imager_Cloud_Detection = .FALSE.
+
+ N__Num_Imager_Chans = 0
+ N__Num_Imager_Clusters = 0
+ N__Imager_Chans(:) = 0
+
+ R__Stddev_Threshold(:) = 0.0_r_kind
+ R__Coverage_Threshold = 0.0_r_kind
+ R__FG_Departure_Threshold = 0.0_r_kind
+
+
+ CASE(INST_ID_IASI)
+ !====================
+ ! Set up IASI
+ !====================
+
+ CL__InstrumentName='IASI'
+ CL__Cloud_Detection_File = 'IASI_CLDDET.NL'
+
+ N__Num_Bands = 5
+
+ N__Band_Size(:) = 0
+ N__Band_Size(1:N__Num_Bands) =(/ 184, 15, 116, 4, 15 /)
+
+ N__Bands(:,:)= 0
+
+ ! Use the "IASI 366" Subset
+ N__Bands(1:N__Band_Size(1),1) = &
+ (/ 16, 38, 49, 51, 55, 57, 59, 61, 63, 66, &
+ 70, 72, 74, 79, 81, 83, 85, 87, 89, 92, &
+ 95, 97, 99, 101, 104, 106, 109, 111, 113, 116, &
+ 119, 122, 125, 128, 131, 133, 135, 138, 141, 144, &
+ 146, 148, 151, 154, 157, 159, 161, 163, 165, 167, &
+ 170, 173, 176, 178, 179, 180, 183, 185, 187, 189, &
+ 191, 193, 195, 197, 199, 201, 203, 205, 207, 210, &
+ 212, 214, 217, 219, 222, 224, 226, 228, 230, 232, &
+ 234, 236, 239, 241, 242, 243, 246, 249, 252, 254, &
+ 256, 258, 260, 262, 265, 267, 269, 271, 272, 273, &
+ 275, 278, 280, 282, 284, 286, 288, 290, 292, 294, &
+ 296, 299, 301, 303, 306, 308, 310, 312, 314, 316, &
+ 318, 320, 323, 325, 327, 329, 331, 333, 335, 341, &
+ 347, 350, 352, 354, 356, 358, 360, 362, 364, 366, &
+ 369, 371, 373, 375, 377, 379, 381, 386, 389, 404, &
+ 407, 410, 414, 416, 426, 428, 432, 434, 445, 457, &
+ 515, 546, 552, 566, 571, 573, 646, 662, 668, 756, &
+ 867, 921, 1027, 1090, 1133, 1191, 1194, 1271, 1805, 1884, &
+ 1946, 1991, 2094, 2239 /)
+
+ N__Bands(1:N__Band_Size(2),2) = &
+ (/ 1479, 1509, 1513, 1521, 1536, 1574, 1579, 1585, 1587, 1626, &
+ 1639, 1643, 1652, 1658, 1671 /)
+
+ N__Bands(1:N__Band_Size(3),3) = &
+ (/ 2119, 2213, 2271, 2321, 2398, 2701, 2741, 2819, 2889, 2907, &
+ 2910, 2919, 2939, 2944, 2948, 2951, 2958, 2977, 2985, 2988, &
+ 2991, 2993, 3002, 3008, 3014, 3027, 3029, 3036, 3047, 3049, &
+ 3053, 3058, 3064, 3069, 3087, 3093, 3098, 3105, 3107, 3110, &
+ 3127, 3136, 3151, 3160, 3165, 3168, 3175, 3178, 3207, 3228, &
+ 3244, 3248, 3252, 3256, 3263, 3281, 3303, 3309, 3312, 3322, &
+ 3375, 3378, 3411, 3438, 3440, 3442, 3444, 3446, 3448, 3450, &
+ 3452, 3454, 3458, 3467, 3476, 3484, 3491, 3497, 3499, 3504, &
+ 3506, 3509, 3518, 3527, 3555, 3575, 3577, 3580, 3582, 3586, &
+ 3589, 3599, 3653, 3658, 3661, 4032, 5368, 5371, 5379, 5381, &
+ 5383, 5397, 5399, 5401, 5403, 5405, 5455, 5480, 5483, 5485, &
+ 5492, 5502, 5507, 5509, 5517, 5558 /)
+
+ N__Bands(1:N__Band_Size(4),4) = &
+ (/ 5988, 5992, 5994, 6003 /)
+
+ N__Bands(1:N__Band_Size(5),5) = &
+ (/ 6982, 6985, 6987, 6989, 6991, 6993, 6995, 6997, 7267, 7269, &
+ 7424, 7426, 7428, 7885, 8007 /)
+
+ N__GradChkInterval(:) = 0
+ N__GradChkInterval(1:N__Num_Bands) = (/12,5,5,5,5 /)
+
+ N__Window_Width(:) = 0
+ N__Window_Width(1:N__Num_Bands) = (/ 10,6,8,5,8 /)
+
+ N__Window_Bounds(:,:) = 0
+ N__Window_Bounds(1,1) = 573
+ N__Window_Bounds(1,2) = 2239
+
+ R__BT_Threshold(:) = 0.0_r_kind
+ R__BT_Threshold(1:N__Num_Bands) = (/ 0.5_r_kind, 0.5_r_kind, 0.5_r_kind, 0.5_r_kind, 0.5_r_kind /)
+
+ R__Grad_Threshold(:) = 0.0_r_kind
+ R__Grad_Threshold(1:N__Num_Bands) = (/ 0.02_r_kind, 0.02_r_kind, 0.02_r_kind, 0.02_r_kind, 0.02_r_kind /)
+
+ R__Window_Grad_Threshold(:) = 0.0_r_kind
+ R__Window_Grad_Threshold(1) = 0.4_r_kind
+
+ L__Do_Quick_Exit = .TRUE.
+
+
+ ! This is cross-band:
+
+ L__Do_CrossBand = .TRUE.
+
+ N__BandToUse(:) = 0
+ N__BandToUse(1:N__Num_Bands) = (/ 1,1,1,1,1 /)
+
+
+ ! This is the setup for imager cloud detection
+
+ L__Do_Imager_Cloud_Detection = .TRUE.
+
+ N__Num_Imager_Chans = 2
+ N__Num_Imager_Clusters = 7
+
+ N__Imager_Chans(1:N__Num_Imager_Chans) = (/ 2, 3 /)
+
+ R__Stddev_Threshold(1:N__Num_Imager_Chans) = (/ 0.75_r_kind, 0.80_r_kind /)
+
+ R__Coverage_Threshold = 0.03_r_kind
+ R__FG_Departure_Threshold = 1.0_r_kind
+
+
+ CASE(INST_ID_CRIS)
+ !====================
+ ! Set up CRIS
+ !====================
+
+ CL__InstrumentName='CRIS'
+ CL__Cloud_Detection_File = 'CRIS_CLDDET.NL'
+
+ N__Num_Bands = 5
+
+ N__Band_Size(:) = 0
+
+ N__Band_Size(1:N__Num_Bands) =(/ 137, 123, 76, 12, 6 /)
+
+ N__Bands(:,:)= 0
+
+ ! Use the "CRIS 300" Subset
+ N__Bands(1:N__Band_Size(1),1) = &
+ (/ 1, 5, 9, 13, 17, 18, 19, 20, 21, 22, &
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, &
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, &
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, &
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, &
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, &
+ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, &
+ 83, 84, 85, 86, 87, 88, 91, 92, 93, 94, &
+ 95, 96, 97, 99, 101, 105, 107, 109, 111, 113, &
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, &
+ 125, 133, 135, 137, 139, 141, 144, 147, 161, 173, &
+ 177, 181, 185, 195, 210, 221, 225, 229, 249, 257, &
+ 269, 273, 293, 301, 317, 333, 349, 369, 409, 433, &
+ 457, 481, 501, 549, 701, 705, 709 /)
+
+ N__Bands(1:N__Band_Size(2),2) = &
+ (/ 3, 6, 7, 8, 10, 12, 14, 15, 16, 89, &
+ 90, 102, 103, 104, 106, 108, 110, 114, 126, 127, &
+ 129, 132, 134, 138, 140, 143, 145, 146, 148, 149, &
+ 150, 151, 153, 155, 156, 157, 158, 159, 162, 163, &
+ 164, 165, 166, 169, 170, 171, 172, 175, 180, 189, &
+ 200, 201, 205, 206, 214, 217, 218, 226, 228, 230, &
+ 231, 233, 236, 237, 240, 241, 245, 248, 252, 264, &
+ 265, 281, 285, 297, 324, 327, 361, 378, 389, 392, &
+ 400, 473, 493, 500, 503, 511, 527, 528, 529, 530, &
+ 531, 534, 538, 542, 544, 545, 547, 550, 553, 555, &
+ 590, 594, 598, 602, 606, 610, 614, 618, 622, 626, &
+ 645, 649, 653, 657, 661, 665, 685, 702, 703, 704, &
+ 706, 707, 713 /)
+
+ N__Bands(1:N__Band_Size(3),3) = &
+ (/ 717, 725, 728, 729, 730, 731, 732, 733, 734, 735, &
+ 736, 741, 749, 757, 765, 773, 781, 789, 794, 797, &
+ 805, 806, 815, 822, 829, 839, 845, 853, 861, 868, &
+ 869, 872, 877, 885, 887, 893, 898, 900, 909, 912, &
+ 915, 917, 921, 929, 933, 941, 949, 957, 963, 965, &
+ 973, 975, 978, 981, 989, 991, 993, 996, 1005, 1014, &
+ 1025, 1029, 1037, 1042, 1053, 1061, 1073, 1077, 1085, 1093, &
+ 1101, 1109, 1117, 1125, 1133, 1141 /)
+
+ N__Bands(1:N__Band_Size(4),4) = &
+ (/ 1149, 1157, 1164, 1165, 1173, 1181, 1189, 1197, 1205, 1213, &
+ 1221, 1251 /)
+
+ N__Bands(1:N__Band_Size(5),5) = &
+ (/ 1189, 1197, 1205, 1213, 1221, 1251 /)
+
+
+ N__GradChkInterval(:) = 0
+ N__GradChkInterval(1:N__Num_Bands) = (/ 5,5,5,3,3 /)
+
+ N__Window_Width(:) = 0
+ N__Window_Width(1:N__Num_Bands) = (/ 6,6,8,3,3 /)
+
+ N__Window_Bounds(:,:) = 0
+ N__Window_Bounds(1,1) = 229
+ N__Window_Bounds(1,2) = 549
+
+ R__BT_Threshold(:) = 0.0_r_kind
+ R__BT_Threshold(1:N__Num_Bands) = (/ 0.5_r_kind, 0.5_r_kind, 0.5_r_kind, 0.5_r_kind, 0.5_r_kind /)
+
+ R__Grad_Threshold(:) = 0.0_r_kind
+ R__Grad_Threshold(1:N__Num_Bands) = (/ 0.02_r_kind, 0.02_r_kind, 0.02_r_kind, 0.02_r_kind, 0.02_r_kind /)
+
+ R__Window_Grad_Threshold(:) = 0.0_r_kind
+ R__Window_Grad_Threshold(1) = 0.4_r_kind
+
+ L__Do_Quick_Exit = .TRUE.
+
+
+ ! This is cross-band:
+
+ L__Do_CrossBand = .TRUE.
+
+ N__BandToUse(:) = 0
+ N__BandToUse(1:N__Num_Bands) = (/ 1,1,1,1,1 /)
+
+
+ ! This is the setup for imager cloud detection
+
+ L__Do_Imager_Cloud_Detection = .FALSE.
+
+ N__Num_Imager_Chans = 0
+ N__Num_Imager_Clusters = 0
+ N__Imager_Chans(:) = 0
+
+ R__Stddev_Threshold(:) = 0.0_r_kind
+ R__Coverage_Threshold = 0.0_r_kind
+ R__FG_Departure_Threshold = 0.0_r_kind
+
+
+ CASE(INST_ID_IRS)
+ !====================
+ ! Set up IRS
+ !====================
+
+ CL__InstrumentName='IRS'
+ CL__Cloud_Detection_File = 'IRS_CLDDET.NL'
+
+ N__Num_Bands = 1
+
+ N__Band_Size(:) = 0
+
+ N__Band_Size(1:N__Num_Bands) =(/ 138 /)
+
+ N__Bands(:,:)= 0
+
+ N__Bands(1:N__Band_Size(1),1) = &
+ (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, &
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, &
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, &
+ 41, 42, 43, 44, 45, 46, 48, 53, 54, 55, &
+ 56, 57, 58, 60, 61, 62, 63, 65, 70, 74, &
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, &
+ 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, &
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, &
+ 106, 107, 108, 109, 118, 119, 131, 145, 163, 169, &
+ 177, 180, 190, 195, 199, 209, 215, 221, 231, 237, &
+ 252, 262, 268, 281, 289, 298, 312, 322, 328, 341, &
+ 347, 359, 375, 384, 390, 404, 412, 421, 648, 656, &
+ 667, 678, 686, 692, 709, 750, 792, 808 /)
+
+ N__GradChkInterval(:) = 0
+ N__GradChkInterval(1:N__Num_Bands) = (/ 12 /)
+
+ N__Window_Width(:) = 0
+ N__Window_Width(1:N__Num_Bands) = (/ 10 /)
+
+ N__Window_Bounds(:,:) = 0
+ N__Window_Bounds(1,1) = 131
+ N__Window_Bounds(1,2) = 808
+
+ R__BT_Threshold(:) = 0.0_r_kind
+ R__BT_Threshold(1:N__Num_Bands) = (/ 0.4_r_kind /)
+
+ R__Grad_Threshold(:) = 0.0_r_kind
+ R__Grad_Threshold(1:N__Num_Bands) = (/ 0.02_r_kind /)
+
+ R__Window_Grad_Threshold(:) = 0.0_r_kind
+ R__Window_Grad_Threshold(1) = 0.4_r_kind
+
+ L__Do_Quick_Exit = .TRUE.
+
+
+ ! This is cross-band:
+
+ L__Do_CrossBand = .TRUE.
+
+ N__BandToUse(:) = 0
+ N__BandToUse(1:N__Num_Bands) = (/ 1 /)
+
+
+ ! This is the setup for imager cloud detection
+
+ L__Do_Imager_Cloud_Detection = .FALSE.
+
+ N__Num_Imager_Chans = 0
+ N__Num_Imager_Clusters = 0
+ N__Imager_Chans(:) = 0
+
+ R__Stddev_Threshold(:) = 0.0_r_kind
+ R__Coverage_Threshold = 0.0_r_kind
+ R__FG_Departure_Threshold = 0.0_r_kind
+
+
+ CASE(INST_ID_IASING)
+ !====================
+ ! Set up IASING
+ !====================
+
+ CL__InstrumentName='IASING'
+ CL__Cloud_Detection_File = 'IASING_CLDDET.NL'
+
+ N__Num_Bands = 1
+
+ N__Band_Size(:) = 0
+
+ N__Band_Size(1:N__Num_Bands) =(/ 254 /)
+
+ N__Bands(:,:)= 0
+
+ N__Bands(1:N__Band_Size(1),1) = &
+ (/ 31, 75, 97, 101, 109, 113, 117, 121, 125, 131, &
+ 139, 143, 147, 157, 161, 165, 169, 173, 177, 183, &
+ 189, 193, 197, 201, 207, 211, 217, 221, 225, 231, &
+ 237, 243, 249, 255, 261, 265, 269, 275, 281, 287, &
+ 291, 295, 301, 307, 313, 317, 321, 325, 329, 333, &
+ 339, 345, 351, 355, 357, 359, 365, 369, 373, 377, &
+ 381, 385, 389, 393, 397, 401, 403, 405, 407, 409, &
+ 411, 413, 415, 417, 419, 421, 423, 425, 427, 429, &
+ 431, 433, 435, 437, 439, 441, 443, 445, 447, 449, &
+ 451, 453, 455, 457, 459, 461, 463, 465, 467, 469, &
+ 471, 473, 475, 477, 479, 481, 483, 485, 487, 489, &
+ 491, 493, 495, 497, 499, 501, 503, 505, 507, 509, &
+ 511, 513, 515, 517, 519, 521, 523, 525, 527, 529, &
+ 531, 533, 535, 537, 539, 541, 543, 545, 547, 549, &
+ 551, 553, 555, 557, 559, 561, 563, 565, 567, 569, &
+ 571, 573, 575, 577, 579, 581, 583, 585, 587, 589, &
+ 591, 593, 595, 597, 601, 603, 605, 607, 609, 611, &
+ 613, 615, 617, 619, 621, 623, 625, 627, 629, 631, &
+ 633, 635, 637, 639, 641, 643, 645, 647, 649, 651, &
+ 653, 655, 657, 659, 661, 663, 665, 667, 669, 681, &
+ 693, 699, 703, 707, 711, 715, 719, 723, 727, 731, &
+ 737, 741, 745, 749, 753, 757, 761, 771, 777, 807, &
+ 813, 819, 827, 831, 851, 855, 863, 867, 889, 913, &
+ 1029, 1091, 1103, 1131, 1141, 1145, 1291, 1323, 1335, 1511, &
+ 1733, 1841, 2053, 2179, 2265, 2381, 2387, 2541, 3609, 3767, &
+ 3891, 3981, 4187, 4477 /)
+
+ N__GradChkInterval(:) = 0
+ N__GradChkInterval(1:N__Num_Bands) = (/ 25 /)
+
+ N__Window_Width(:) = 0
+ N__Window_Width(1:N__Num_Bands) = (/ 20 /)
+
+ N__Window_Bounds(:,:) = 0
+ N__Window_Bounds(1,1) = 1145
+ N__Window_Bounds(1,2) = 4477
+
+ R__BT_Threshold(:) = 0.0_r_kind
+ R__BT_Threshold(1:N__Num_Bands) = (/ 0.27_r_kind /)
+
+ R__Grad_Threshold(:) = 0.0_r_kind
+ R__Grad_Threshold(1:N__Num_Bands) = (/ 0.02_r_kind /)
+
+ R__Window_Grad_Threshold(:) = 0.0_r_kind
+ R__Window_Grad_Threshold(1) = 0.4_r_kind
+
+ L__Do_Quick_Exit = .TRUE.
+
+
+ ! This is cross-band:
+
+ L__Do_CrossBand = .TRUE.
+
+ N__BandToUse(:) = 0
+ N__BandToUse(1:N__Num_Bands) = (/ 1 /)
+
+ ! This is the setup for imager cloud detection
+
+ L__Do_Imager_Cloud_Detection = .FALSE.
+
+ N__Num_Imager_Chans = 0
+ N__Num_Imager_Clusters = 0
+ N__Imager_Chans(:) = 0
+
+ R__Stddev_Threshold(:) = 0.0_r_kind
+ R__Coverage_Threshold = 0.0_r_kind
+ R__FG_Departure_Threshold = 0.0_r_kind
+
+
+ END SELECT
+
+ !------------------------------------------------------------------
+ ! Open and read file containing cloud detection setup for the
+ ! current instrument
+ !------------------------------------------------------------------
+
+ INIU1=107
+ OPEN(INIU1,STATUS='OLD',FORM='FORMATTED', &
+ FILE=TRIM(CL__Cloud_Detection_File), IOSTAT=IOS)
+ IF (IOS == 0) THEN
+ READ(INIU1,nml=Cloud_Detect_Coeffs,IOSTAT=IOS)
+ IF (IOS == 0) THEN
+ if ( verbose ) WRITE(*,'(3X,A)') TRIM(CL__InstrumentName) // &
+ ' CLOUD DETECTION FILE READ OK'
+ ELSE
+ CALL CADS_Abort('PROBLEM READING '//TRIM(CL__InstrumentName)//&
+ 'CLOUD DETECTION FILE')
+ ENDIF
+ CLOSE(INIU1)
+ ELSE
+ if ( verbose ) WRITE(*,'(3X,A)') 'NO '//TRIM(CL__InstrumentName) // &
+ ' CLOUD DETECTION FILE : Using Default Values'
+ ENDIF
+
+ IF (MAXVAL(N__Band_Size(:)) > JP__Max_Channels) &
+ CALL CADS_Abort('Too many channels specified in cloud '//&
+ 'detection - increase JP__Max_Channels')
+
+
+ M__Sensor = J__SENSOR
+
+ !------------------------------------------------------------------
+ ! Set up the S__CADS_Setup_Cloud structure for current sensor
+ !------------------------------------------------------------------
+
+ S__CADS_Setup_Cloud(J__SENSOR) % M__SENSOR = M__Sensor
+
+ S__CADS_Setup_Cloud(J__SENSOR) % N__Num_Bands = N__Num_Bands
+
+ ALLOCATE( S__CADS_Setup_Cloud(J__SENSOR) % N__Band_Size(N__Num_Bands) )
+
+ S__CADS_Setup_Cloud(J__SENSOR) % N__Band_Size(:) = &
+ N__Band_Size(1:N__Num_Bands)
+
+ ALLOCATE(S__CADS_Setup_Cloud(J__SENSOR) % N__Bands &
+ (MAXVAL(N__Band_Size(:)), N__Num_Bands))
+
+ S__CADS_Setup_Cloud(J__SENSOR) % N__Bands(:,:) = 0
+
+ DO J = 1, N__Num_Bands
+ S__CADS_Setup_Cloud(J__SENSOR) % N__Bands(1:N__Band_Size(J),J) = &
+ N__Bands(1:N__Band_Size(J),J)
+ ENDDO
+
+ ALLOCATE( S__CADS_Setup_Cloud(J__SENSOR) % N__Window_Width(N__Num_Bands) )
+
+ S__CADS_Setup_Cloud(J__SENSOR) % N__Window_Width(:) = &
+ N__Window_Width(1:N__Num_Bands)
+
+ ALLOCATE( S__CADS_Setup_Cloud(J__SENSOR) % R__BT_Threshold(N__Num_Bands) )
+ S__CADS_Setup_Cloud(J__SENSOR) % R__BT_Threshold(:) = &
+ R__BT_Threshold(1:N__Num_Bands)
+
+ ALLOCATE(S__CADS_Setup_Cloud(J__SENSOR) % R__Grad_Threshold(N__Num_Bands))
+ S__CADS_Setup_Cloud(J__SENSOR) % R__Grad_Threshold(:) = &
+ R__Grad_Threshold(1:N__Num_Bands)
+
+ ALLOCATE(S__CADS_Setup_Cloud(J__SENSOR) % &
+ R__Window_Grad_Threshold(N__Num_Bands))
+
+ S__CADS_Setup_Cloud(J__SENSOR) % R__Window_Grad_Threshold(:) = &
+ R__Window_Grad_Threshold(1:N__Num_Bands)
+
+ ALLOCATE(S__CADS_Setup_Cloud(J__SENSOR) % N__GradChkInterval(N__Num_Bands))
+ S__CADS_Setup_Cloud(J__SENSOR) % N__GradChkInterval(:) = &
+ N__GradChkInterval(1:N__Num_Bands)
+
+ ALLOCATE(S__CADS_Setup_Cloud(J__SENSOR) % N__Window_Bounds(N__Num_Bands,2))
+ S__CADS_Setup_Cloud(J__SENSOR) % N__Window_Bounds(:,:) = &
+ N__Window_Bounds(1:N__Num_Bands,:)
+
+ S__CADS_Setup_Cloud(J__SENSOR) % L__Do_Quick_Exit = L__Do_Quick_Exit
+
+
+ !-------------
+ ! Cross Band
+ !-------------
+
+ S__CADS_Setup_Cloud(J__SENSOR) % L__Do_CrossBand = L__Do_CrossBand
+
+ ALLOCATE( S__CADS_Setup_Cloud(J__SENSOR) % N__BandToUse(N__Num_Bands) )
+ S__CADS_Setup_Cloud(J__SENSOR) % N__BandToUse(:) = &
+ N__BandToUse(1:N__Num_Bands)
+
+
+ !-------------
+ ! Imager cloud detection
+ !-------------
+
+ S__CADS_Setup_Cloud(J__SENSOR) % L__Do_Imager_Cloud_Detection = &
+ L__Do_Imager_Cloud_Detection
+
+ S__CADS_Setup_Cloud(J__SENSOR) % N__Num_Imager_Chans = &
+ N__Num_Imager_Chans
+
+ S__CADS_Setup_Cloud(J__SENSOR) % N__Num_Imager_Clusters = &
+ N__Num_Imager_Clusters
+
+ ALLOCATE( S__CADS_Setup_Cloud(J__SENSOR) % &
+ N__Imager_Chans(N__Num_Imager_Chans))
+ S__CADS_Setup_Cloud(J__SENSOR) % N__Imager_Chans(:) = &
+ N__Imager_Chans(1:N__Num_Imager_Chans)
+
+ ALLOCATE( S__CADS_Setup_Cloud(J__SENSOR) % &
+ R__Stddev_Threshold(N__Num_Imager_Chans))
+ S__CADS_Setup_Cloud(J__SENSOR) % R__Stddev_Threshold(:) = &
+ R__Stddev_Threshold(1:N__Num_Imager_Chans)
+
+ S__CADS_Setup_Cloud(J__SENSOR) % R__Coverage_Threshold = &
+ R__Coverage_Threshold
+
+ S__CADS_Setup_Cloud(J__SENSOR) % R__FG_Departure_Threshold = &
+ R__FG_Departure_Threshold
+
+ ENDDO SensorLoop
+
+END SUBROUTINE CADS_SETUP_CLOUD
+
+SUBROUTINE CADS_Detect_Cloud( K__Sensor, K__NChans, K__ChanID, K__Minlev, K__Maxlev, &
+ K__Num_Imager_Chans, K__Chan_ID_Imager, K__Num_Imager_Clusters, &
+ K__Cloud_Flag, P__ObsBTs, P__ModelBTs, P__Chan_Level, P__Cluster_Fraction,&
+ P__BT_in_Cluster, P__BT_Overall_SDev, P__BT_Model_Imager, Z__Cloud_Level )
+
+! This software was developed within the context of the EUMETSAT
+! Satellite Application Facility on Numerical Weather Prediction
+! (NWP SAF), under the Cooperation Agreement dated 7 December 2016,
+! between EUMETSAT and the Met Office, UK, by one or more partners
+! within the NWP SAF. The partners in the NWP SAF are the Met
+! Office, ECMWF, DWD and MeteoFrance.
+
+! Copyright 2020, EUMETSAT, All Rights Reserved.
+
+! * CADS_Detect_Cloud *
+! Phil Watts ECMWF 21/01/02
+
+! * PURPOSE *
+! -----------
+! Flag the presence or otherwise of cloud contamination in AIRS/IASI
+! channels using a rank-sorted/model difference method. Currently
+! only a digital filter is supported.
+
+
+! * INTERFACE *
+! -------------
+! *CALL* * CADS_Detect_Cloud( )* (from CADS_Main)
+! WHERE K__Sensor : Satellite sensor (AIRS/IASI/CrIS)
+! K__NChans : Number of channels
+! K__ChanID : Channel indices of input channels
+! K__Minlev : Highest allowed starting point for the cloud search
+! K__Maxlev : Lowest allowed starting point in the initial cloud search
+! K__Num_Imager_Chans : Number of collocated imager channels
+! K__Chan_ID_Imager : Collocated imager channel indices
+! K__Num_Imager_Clusters : Number of collocated clusters
+! K__Cloud_Flag : Cloud flag by channel; 0=clear, 1=cloudy
+! P__ObsBTs : Potentially cloud-affected observed BTs
+! P__ModelBTs : Clear background brightness temperatures (BTs)
+! P__Chan_Level : Channel height assignments
+! P__Cluster_Fraction : Fractional coverage of each cluster within FOV
+! P__BT_in_Cluster : Cluster-mean brightness temperature (BT) on each channel
+! P__BT_Overall_SDev : Overall BT standard deviation on each channel
+! P__BT_Model_Imager : Forward-modelled BT on each channel
+! Z__Cloud_Level : Cloud height assignment
+
+! * EXTERNALS *
+! -------------
+! CADS_Detect_Cloud_Imager, CADS_Detect_Cloud_Heapsort,
+! CADS_Detect_Cloud_Smooth, CADS_Detect_Cloud_Scenario,
+! CADS_Detect_Cloud_Separator
+
+! * MODIFICATIONS *
+! -----------------
+! A.Collard 1.0 01/02/06 Original export version
+! A.Collard 1.0.1 03/05/06 Allow for missing channels
+! A.Collard 1.0.2 04/05/06 Allow cross-band cloud detection
+! A.Collard 1.0.3 15/01/07 Initialise with automatic cross-band for
+! all channels from band 1 for IASI
+! R.Eresmaa 1.1 17/11/09 Include parameters of the Quick Exit /
+! long-wave window gradient check.
+! Pass K__Chan_Low to CF_DIGITAL to allow
+! detecting cirrus in case of compensating
+! humidity bg error in PBL.
+! R.Eresmaa 1.2 11/11/11 Modify the cross-band option to be based
+! on the lowest clear channel rather than
+! on the highest cloud-contaminated one
+! R.Eresmaa 2.0 27/11/13 Add input cloud flag based on collocated
+! imager data
+! R.Eresmaa 2.1 13/01/15 Make array size specifications implicit.
+! R.Eresmaa 2.2 10/11/15 Instrument ID naming convention made
+! consistent with RTTOV.
+! Changed setting of the aerosol flag.
+! R.Eresmaa 2.2.1 13/11/15 Don't allow flagging missing channels clear
+! through the cross-band option.
+! R.Eresmaa 2.3 20/12/16 Remove the call to aerosol detection.
+! R.Eresmaa 2.4 05/02/19 Explicit KIND specifications.
+! R.Eresmaa 3.0 16/04/20 Move the call to imager-based detection here.
+
+ use kinds, only: i_kind, r_kind
+ use gsi_io, only: verbose
+ IMPLICIT NONE
+
+!* 0.1 Global arrays
+ INTEGER(i_kind), INTENT(IN) :: K__Sensor ! Sensor
+ INTEGER(i_kind), INTENT(IN) :: K__NChans ! No. of channels
+ INTEGER(i_kind), INTENT(IN) :: K__ChanID(:) ! Channel IDs
+ INTEGER(i_kind), INTENT(IN) :: K__Minlev ! Highest starting point for cloud search
+ INTEGER(i_kind), INTENT(IN) :: K__Maxlev ! Lowest starting point in the initial search
+ INTEGER(i_kind), INTENT(IN) :: K__Num_Imager_Chans ! No. of imager channels
+ INTEGER(i_kind), INTENT(IN) :: K__Chan_ID_Imager(:) ! Imager channel IDs
+ INTEGER(i_kind), INTENT(IN) :: K__Num_Imager_Clusters ! No. of imager clusters
+ INTEGER(i_kind), INTENT(OUT) :: K__Cloud_Flag(:) ! Output cloud flags
+ REAL(r_kind), INTENT(IN) :: P__ObsBTs(:) ! Observed BTs
+ REAL(r_kind), INTENT(IN) :: P__ModelBTs(:) ! Model clear BTs
+ REAL(r_kind), INTENT(IN) :: P__Chan_Level(:) ! Channel height assignments
+ REAL(r_kind), INTENT(IN) :: P__Cluster_Fraction(:) ! Cluster coverages
+ REAL(r_kind), INTENT(IN) :: P__BT_in_Cluster(:,:) ! Mean BT in cluster / channel
+ REAL(r_kind), INTENT(IN) :: P__BT_Overall_Sdev(:) ! St.Dev of imager BT in FOV
+ REAL(r_kind), INTENT(IN) :: P__BT_Model_Imager(:) ! Model-based estimate of imager BT
+ REAL(r_kind), INTENT(OUT) :: Z__Cloud_Level ! Cloud hight assignment
+
+!* 0.2 local variables
+ INTEGER(i_kind) :: IST,ICOUNT,J,I_K,JBAND,JBAND2
+ INTEGER(i_kind) :: I__Imager_Flag ! Preliminary cloud flag from collocated imager data
+
+!* 0.3 Local variables - band splitting details
+ INTEGER(i_kind), POINTER :: I__Bands(:,:) ! Channel bands
+ INTEGER(i_kind), POINTER :: I__Band_Size(:) ! Number of channels per band
+ INTEGER(i_kind), POINTER :: I__BandToUse(:) ! Cross-band definitions
+ INTEGER(i_kind) :: I__Num_Bands ! Number of bands
+ INTEGER(i_kind) :: I__NumFoundChans ! Number of usable channels
+ INTEGER(i_kind) :: I__BandNumber(K__NChans) ! Channel band indicator
+ INTEGER(i_kind) :: I__WindowBounds(2) ! Boundary of window
+ INTEGER(i_kind) :: I__Window_Chans(2) ! Boundary of long-wave window
+ INTEGER(i_kind), ALLOCATABLE :: I__INDEX(:) ! Channel ranking within a band
+ INTEGER(i_kind), ALLOCATABLE :: IDCHAN(:) ! Overall channel ranking
+ INTEGER(i_kind), ALLOCATABLE :: I__Cloud_Flag(:) ! Rank-sorted output cloud flags
+ INTEGER(i_kind) :: I__Scenario_Index ! 1--Quick Exit, 2--Warm Start, 3--Cold Start
+ INTEGER(i_kind) :: I__Start_Channel ! Final starting channel in the cloud search
+
+ LOGICAL :: LL__Do_CrossBand
+
+! Input array projections (handling one detection band at a time)
+ REAL(r_kind), ALLOCATABLE :: Z__DBT(:) ! Original departures
+ REAL(r_kind), ALLOCATABLE :: Z__Smooth_DBT(:) ! Smoothed departures
+ REAL(r_kind), ALLOCATABLE :: Z__LEVEL(:) ! Channel height assignments
+
+!* 0.4 Local variables - digital filter parameters
+ INTEGER(i_kind) :: I__CHAN_HIGH ! Channel at K__Minlev
+ INTEGER(i_kind) :: I__CHAN_LOW ! Channel at K__Maxlev
+ INTEGER(i_kind) :: I__FirstCloudyChannel ! Highest cloud-affected channel
+ INTEGER(i_kind) :: I__LastClearChannel ! Lowest clear channel
+ INTEGER(i_kind),POINTER :: I__Window_Width(:) ! Box-car filter width
+ INTEGER(i_kind),POINTER :: I__GradChkInterval(:) ! Gradient-check interval
+
+!======================================================================
+
+
+! Get correct processing parameters for this sensor:
+ I__Num_Bands = S__CADS_Setup_Cloud(K__Sensor) % N__Num_Bands
+ I__Band_Size => S__CADS_Setup_Cloud(K__Sensor) % N__Band_Size
+ I__Bands => S__CADS_Setup_Cloud(K__Sensor) % N__Bands
+ I__Window_Width => S__CADS_Setup_Cloud(K__Sensor) % N__Window_Width
+ I__BandToUse => S__CADS_Setup_Cloud(K__Sensor) % N__BandToUse
+ LL__Do_CrossBand = S__CADS_Setup_Cloud(K__Sensor) % L__Do_CrossBand
+ I__GradChkInterval => S__CADS_Setup_Cloud(K__Sensor) % N__GradChkInterval
+
+
+! Initialise
+ K__Cloud_Flag(:)=1 ! intialise ALL channels to cloudy
+
+
+! Imager-based cloud detection
+ I__Imager_Flag=0 ! Default assumption: no cloud affecting collocated imager data
+ CALL CADS_Detect_Cloud_Imager( K__Sensor, K__Num_Imager_Chans, K__Chan_ID_Imager, K__Num_Imager_Clusters, &
+ I__Imager_Flag, P__Cluster_Fraction, P__BT_in_Cluster, P__BT_Overall_SDev, P__BT_Model_Imager )
+
+! If using cross-band, set up an array indicating which channels correspond
+! to which bands in K__ChanID
+ IF (LL__Do_CrossBand) THEN
+ I__BandNumber(:)=-1 ! Initialise
+ DO JBAND = 1, I__Num_Bands
+ DO I_K=1,K__NChans
+ IF (ANY(I__BANDS(:,JBAND) == K__ChanID(I_K))) &
+ I__BandNumber(I_K)=JBand
+ ENDDO
+ ENDDO
+ ENDIF
+
+
+!1 Loop over bands
+ Band_Loop: DO JBAND = 1, I__Num_Bands
+
+ ! Don't bother doing the cloud detection if we're just going to use
+ ! the results from another band anyway:
+ IF (LL__Do_CrossBand) THEN
+ IF (.NOT.(ANY(I__BandToUse(:) == JBAND))) CYCLE
+ ENDIF
+
+ ALLOCATE (Z__DBT(I__Band_Size(JBAND)))
+ Z__DBT(:) = 0.0_r_kind
+
+ ALLOCATE (Z__LEVEL(I__Band_Size(JBAND)))
+ Z__LEVEL(:) = REAL(K__Maxlev)
+
+ ALLOCATE (I__Cloud_Flag(I__Band_Size(JBAND)))
+ ALLOCATE (I__INDEX(I__Band_Size(JBAND)))
+
+ ALLOCATE (IDCHAN(I__Band_Size(JBAND)))
+ IDCHAN(:) = 1
+
+
+ I__WindowBounds(:) = &
+ S__CADS_Setup_Cloud(K__Sensor) % N__Window_Bounds(JBand,:)
+
+!1.1 find channels within current band --------------------------------------
+ I__NumFoundChans = 0
+ I__Window_Chans(:) = -1
+
+ DO J=1,I__Band_Size(JBAND)
+ DO I_K=1,K__NChans
+ IF (K__ChanID(I_K) == I__BANDS(J,JBAND)) THEN
+! IF (P__ObsBTs(I_K) < 0. .OR. P__ModelBTs(I_K) < 0.) CYCLE
+ IF (P__ObsBTs(I_K) < 60.0_r_kind .OR. P__ModelBTs(I_K) < 60.0_r_kind) CYCLE ! Missing channels are set to 50.0K
+ I__NumFoundChans = I__NumFoundChans + 1
+ Z__DBT(I__NumFoundChans)=P__ObsBTs(I_K)-P__ModelBTs(I_K)
+ Z__LEVEL(I__NumFoundChans)=P__Chan_Level(I_K)
+ I__INDEX(I__NumFoundChans)=I__NumFoundChans
+ IDCHAN(I__NumFoundChans)=I_K
+ IF (K__ChanID(I_K) == I__WindowBounds(1)) &
+ I__Window_Chans(1) = I__NumFoundChans
+ IF (K__ChanID(I_K) == I__WindowBounds(2)) &
+ I__Window_Chans(2) = I__NumFoundChans
+ ENDIF
+ ENDDO
+ ENDDO
+ IF ( I__NumFoundChans == 0 ) THEN
+ if (verbose) WRITE(*,*) &
+ '**CADS_Detect_Cloud - WARNING: ' // &
+ 'CHANNELS NOT FOUND CYCLING BAND: **', JBAND
+ IF (ALLOCATED(Z__DBT)) DEALLOCATE (Z__DBT)
+ IF (ALLOCATED(Z__LEVEL)) DEALLOCATE (Z__LEVEL)
+ IF (ALLOCATED(I__Cloud_Flag)) DEALLOCATE (I__Cloud_Flag)
+ IF (ALLOCATED(I__INDEX)) DEALLOCATE (I__INDEX)
+ IF (ALLOCATED(IDCHAN)) DEALLOCATE (IDCHAN)
+ CYCLE Band_Loop
+ ENDIF
+
+!----------------------------------------------------------------------------
+ IST=0
+ ICOUNT=I__NumFoundChans
+ I__Cloud_Flag(:)=1
+
+!2. Sort according to channel height assignments
+ CALL CADS_Detect_Cloud_Heapsort(I__NumFoundChans,Z__Level,I__Index)
+
+!2.1 Find I__CHAN_LOW - lowest channel considered in the initial cloud search
+ J=1
+ DO WHILE (J < I__NumFoundChans .AND. Z__Level(I__Index(J)) < REAL(K__Maxlev))
+ J=J+1
+ ENDDO
+
+ IF (J == I__NumFoundChans) THEN
+ I__CHAN_LOW = I__NumFoundChans-1
+ ELSE
+ I__CHAN_LOW = J
+ ENDIF
+ IF(I__CHAN_LOW <= 1)I__CHAN_LOW=1
+
+!2.1a Find I__CHAN_HIGH - highest allowed channel for starting the cloud search
+ J=1
+ DO WHILE (J < I__NumFoundChans .AND. Z__Level(I__Index(J)) < REAL(K__Minlev))
+ J=J+1
+ ENDDO
+ I__CHAN_HIGH=J
+
+
+! Smoothing
+ ALLOCATE (Z__Smooth_DBT(I__NumFoundChans))
+ Z__Smooth_DBT(:) = 0.0_r_kind
+
+ CALL CADS_Detect_Cloud_Smooth( I__NumFoundChans, I__Window_Width(JBAND), Z__DBT(I__INDEX(1:I__NumFoundChans)), &
+ Z__Smooth_DBT(1:I__NumFoundChans) )
+
+
+!3. Choice of cloud detection scenario
+
+ CALL CADS_Detect_Cloud_Scenario( K__Sensor, JBAND, I__NumFoundChans, I__GradChkInterval(JBAND), I__Index(1:I__NumFoundChans), &
+ I__CHAN_HIGH, I__CHAN_LOW, I__Window_Chans, I__Imager_Flag, I__Scenario_Index, I__Start_Channel, Z__Smooth_DBT(1:I__NumFoundChans))
+
+
+!4. Identify the separation between clear/cloudy channels
+
+ CALL CADS_Detect_Cloud_Separator( K__Sensor, JBAND, I__NumFoundChans, I__GradChkInterval(JBAND), I__Index(1:I__NumFoundChans), &
+ I__Cloud_Flag, I__FirstCloudyChannel, I__LastClearChannel, I__Scenario_Index, I__Start_Channel, Z__Smooth_DBT(1:I__NumFoundChans))
+
+ K__Cloud_Flag(IDCHAN(1:I__NumFoundChans)) = &
+ I__Cloud_Flag(1:I__NumFoundChans)
+
+ ! Set cloud level for cross-band:
+ IF (I__FirstCloudyChannel == 0) THEN ! FOV is completely clear
+ Z__Cloud_Level = 1.e20_r_kind ! Large value
+ ELSE
+ Z__Cloud_Level = P__Chan_Level(IDCHAN(I__LastClearChannel))
+ ENDIF
+
+ ! Automatically do cross band cloud detection for all
+ ! interferometer channels (whether assigned a band or not) if
+ ! JBand == 1. This can be over-ridden for the other bands.
+
+ IF (K__Sensor /= INST_ID_AIRS .AND. JBand == 1) &
+ WHERE(P__Chan_Level(:) < Z__Cloud_Level) K__Cloud_Flag(:) = 0
+
+ CrossBand : IF (LL__Do_CrossBand) THEN
+ ! Cross Band:
+ ! Loop through bands applying cloud detection to those that take their
+ ! cloud detection information from the current band JBAND.
+ DO JBand2 = 1, I__Num_Bands
+ IF (I__BandToUse(JBand2) == JBand) THEN
+ WHERE(P__Chan_Level(:) < Z__Cloud_Level .AND. &
+ I__BandNumber == JBand2 .AND. &
+ P__OBSBTs(:)>0.0_r_kind ) K__Cloud_Flag(:) = 0
+ ENDIF
+ ENDDO
+ ENDIF CrossBand
+
+! Deallocate arrays
+ IF (ALLOCATED(Z__DBT)) DEALLOCATE (Z__DBT)
+ IF (ALLOCATED(Z__Smooth_DBT)) DEALLOCATE (Z__Smooth_DBT)
+ IF (ALLOCATED(Z__LEVEL)) DEALLOCATE (Z__LEVEL)
+ IF (ALLOCATED(I__Cloud_Flag)) DEALLOCATE (I__Cloud_Flag)
+ IF (ALLOCATED(I__INDEX)) DEALLOCATE (I__INDEX)
+ IF (ALLOCATED(IDCHAN)) DEALLOCATE (IDCHAN)
+
+ ENDDO Band_Loop
+
+! Nullify pointers
+ NULLIFY(I__Band_Size, I__Bands, I__Window_Width, I__BandToUse)
+
+END SUBROUTINE CADS_Detect_Cloud
+
+SUBROUTINE CADS_Detect_Cloud_Imager( K__Sensor, K__Nchans, K__Chanid, K__Nclust, K__Cloud_Flag, P__Cl_Fraction, &
+ P__Cl_Mean, P__Ov_Stddev, P__FG_BT )
+
+! This software was developed within the context of the EUMETSAT
+! Satellite Application Facility on Numerical Weather Prediction
+! (NWP SAF), under the Cooperation Agreement dated 7 December 2016,
+! between EUMETSAT and the Met Office, UK, by one or more partners
+! within the NWP SAF. The partners in the NWP SAF are the Met
+! Office, ECMWF, DWD and MeteoFrance.
+!
+! Copyright 2020, EUMETSAT, All Rights Reserved.
+
+! *CADS_Detect_Cloud_Imager*
+! R.Eresmaa ECMWF 12/02/13
+
+! * PURPOSE *
+! -----------
+! Provide additional information for the cloud detection by making use
+! of collocated imager data, such as AVHRR collocated with IASI.
+
+! * INTERFACE *
+! -------------
+! *CALL* * CADS_Detect_Cloud_Imager( )* (from CADS_Detect_Cloud)
+! WHERE K__Sensor : Satellite sensor id
+! K__Nchans : Number of channels received as input
+! K__Chanid : Provided channel IDs
+! K__Nclust : Highest possible number of clusters
+! K__Cloud_Flag : Output cloud flag (0-7, 0=clear)
+! P__Cl_Fraction : Fractional coverage of each cluster within FOV
+! P__Cl_Mean : Cluster-mean brightness temperature (BT) on each
+! channel
+! P__Ov_Stddev : Overall BT standard deviation on each channel
+! P__FG_BT : Forward-modelled BT on each channel
+
+! * METHOD *
+! ----------
+! A preliminary indicator of presence of clouds in the sounder
+! field-of-view (FOV) is derived using statistical radiance information
+! within collocated clusters of imager pixels.
+
+! * MODIFICATIONS *
+! -----------------
+! 03/12/13 R.Eresmaa 2.0 Original export version.
+! 19/01/15 R.Eresmaa 2.1 Make array size specifications implicit.
+! Verify that channels intended to be used
+! are received as input.
+! 05/02/19 R.Eresmaa 2.4 Explicit kind specifications.
+! 16/04/20 R.Eresmaa 3.0 Rename and tidy up.
+
+ use kinds, only: i_kind, r_kind
+ IMPLICIT NONE
+
+!* Global arrays
+ INTEGER(i_kind), INTENT(IN) :: K__Sensor ! Sensor id
+ INTEGER(i_kind), INTENT(IN) :: K__Nchans ! No. of channels
+ INTEGER(i_kind), INTENT(IN) :: K__Chanid(:) ! Channel IDs
+ INTEGER(i_kind), INTENT(IN) :: K__Nclust ! No. of clusters
+ INTEGER(i_kind), INTENT(OUT) :: K__Cloud_Flag ! Output cloud flag
+ REAL(r_kind), INTENT(IN) :: P__Cl_Fraction(:) ! Cluster fractions
+ REAL(r_kind), INTENT(IN) :: P__Cl_Mean(:,:) ! Cluster-mean BTs
+ REAL(r_kind), INTENT(IN) :: P__Ov_Stddev(:) ! Overall BT st.devs.
+ REAL(r_kind), INTENT(IN) :: P__FG_BT(:) ! First guess BT
+
+!* Local variables - Setup of the imager cloud detection
+ INTEGER(i_kind) :: I__Num_Imager_Chans ! No. of used channels
+ INTEGER(i_kind), POINTER :: I__Imager_Chans(:) ! List of used channels
+ REAL(r_kind), POINTER :: Z__Stddev_Threshold(:) ! Homogeneity thresholds
+ REAL(r_kind) :: Z__Coverage_Threshold ! Coverage threshold
+ REAL(r_kind) :: Z__FG_Departure_Threshold ! FG departure threshold
+
+!* Additional local variables
+ INTEGER(i_kind) :: I, J, IK, I_Temp_Flag, ICOUNT
+ INTEGER(i_kind) :: I__Chan_Index(K__Nchans)
+ REAL(r_kind) :: Z__Wsqdev, Z__Intercluster
+ REAL(r_kind),dimension(K__Nclust) :: Z__Sqdev
+
+
+
+!* 1.0 Initialize cloud flags as clear
+
+ K__Cloud_Flag=0
+
+ IF (S__CADS_Setup_Cloud(K__Sensor) % L__Do_Imager_Cloud_Detection) THEN
+
+
+!* 1.1 Setup
+
+ I__Num_Imager_Chans = &
+ S__CADS_Setup_Cloud(K__Sensor) % N__Num_Imager_Chans
+ I__Imager_Chans => &
+ S__CADS_Setup_Cloud(K__Sensor) % N__Imager_Chans
+ Z__Stddev_Threshold => &
+ S__CADS_Setup_Cloud(K__Sensor) % R__Stddev_Threshold
+ Z__Coverage_Threshold = &
+ S__CADS_Setup_Cloud(K__Sensor) % R__Coverage_Threshold
+ Z__FG_Departure_Threshold = &
+ S__CADS_Setup_Cloud(K__Sensor) % R__FG_Departure_Threshold
+
+
+
+!* 1.2 Channel indexing
+ I__Chan_Index(:) = 0
+ ICOUNT=0
+ DO I=1,K__Nchans
+ IK=0
+ DO J=1,I__Num_Imager_Chans
+ IF (K__Chanid(I)==I__Imager_Chans(J)) THEN
+ ICOUNT=ICOUNT+1
+ IK=ICOUNT
+ EXIT
+ ENDIF
+ ENDDO
+ I__Chan_Index(I)=IK
+ ENDDO
+
+
+!* 2.0 Compute squared first guess departures for each cluster
+
+ DO J=1,K__Nclust
+ Z__Sqdev(J) = 0.0_r_kind
+ DO I=1,K__Nchans
+ IF (I__Chan_Index(I)==0) CYCLE
+ Z__Sqdev(J) = Z__Sqdev(J) + (P__Cl_Mean(I,J)-P__FG_BT(I))**2
+ ENDDO
+ ENDDO
+
+!* 2.1 Homogeneity check: Do not diagnose presence of cloud if BT
+! standard deviation falls below given threshold on at least one
+! channel.
+
+ I_Temp_Flag=1
+ DO I=1,K__Nchans
+ IF (I__Chan_Index(I)==0) CYCLE
+ IF (P__Ov_Stddev(I)Z__Sqdev(J) .OR. Z__Intercluster>Z__Sqdev(IK)) THEN
+ K__Cloud_Flag=K__Cloud_Flag+2
+ Exit Consistency_Check
+ ENDIF
+ ENDDO
+ ENDDO Consistency_Check
+
+
+!* 2.3 First guess departure check: Do not diagnose presence of cloud
+! if fraction-weighted first guess departure falls below given
+! threshold.
+
+ Z__Wsqdev = SUM(P__Cl_Fraction(:)*Z__Sqdev(:))
+ IF (Z__Wsqdev>=Z__FG_Departure_Threshold) K__Cloud_Flag=K__Cloud_Flag+1
+
+ ENDIF ! L__Do_Imager_Cloud_Detection
+
+END SUBROUTINE CADS_Detect_Cloud_Imager
+
+
+SUBROUTINE CADS_Detect_Cloud_Heapsort(N, A, K_Index)
+
+! This software was developed within the context of the EUMETSAT
+! Satellite Application Facility on Numerical Weather Prediction
+! (NWP SAF), under the Cooperation Agreement dated 7 December 2016,
+! between EUMETSAT and the Met Office, UK, by one or more partners
+! within the NWP SAF. The partners in the NWP SAF are the Met
+! Office, ECMWF, DWD and MeteoFrance.
+!
+! Copyright 2020, EUMETSAT, All Rights Reserved.
+
+! * CADS_Detect_Cloud_Heapsort *
+! A.Collard ECMWF 01/02/06
+
+! * PURPOSE *
+! -----------
+! Basic heapsort algorithm.
+
+! * INTERFACE *
+! -------------
+! *CALL* * CADS_Detect_Cloud_Heapsort( )* (from CADS_Detect_Cloud)
+! WHERE N : Length of input array
+! A : Real input array
+! K_Index : Output ranked array
+
+! * MODIFICATIONS *
+! -----------------
+! 16/05/06 A.Collard 1.0 Original version.
+! 05/02/19 R.Eresmaa 2.4 Explicit KIND specifications
+! 16/04/20 R.Eresmaa 3.0 Rename as part of the big clean for CADS V3
+
+
+ use kinds, only: i_kind, r_kind
+ IMPLICIT NONE
+
+! Subroutine arguments
+ INTEGER(i_kind), INTENT(IN) :: N
+ REAL(r_kind), INTENT(IN) :: A(:)
+ INTEGER(i_kind), INTENT(INOUT) :: K_Index(:)
+
+ INTEGER(i_kind) :: I,J,RIGHT,LEFT,IDX
+ REAL(r_kind) :: TMP
+
+!------------------------------------------
+
+ IF (N <= 1) RETURN
+ LEFT = N/2+1
+ RIGHT = N
+
+ DO
+ IF (LEFT > 1) THEN
+ LEFT = LEFT - 1
+ IDX = K_Index(LEFT)
+ ELSE
+ IDX = K_Index(RIGHT)
+ K_Index(RIGHT) = K_Index(1)
+ RIGHT = RIGHT - 1
+ IF (RIGHT == 1) THEN
+ K_Index(1) = IDX
+ EXIT
+ ENDIF
+ ENDIF
+ TMP = A(IDX)
+ I = LEFT
+ J = 2*LEFT
+ DO WHILE (J <= RIGHT)
+ IF (J < RIGHT) THEN
+ IF (A(K_Index(J)) < A(K_Index(J+1))) J = J + 1
+ ENDIF
+ IF (TMP < A(K_Index(J))) THEN
+ K_Index(I) = K_Index(J)
+ I = J
+ J = 2*J
+ ELSE
+ J = RIGHT + 1
+ ENDIF
+ ENDDO
+ K_Index(I) = IDX
+ ENDDO
+
+END SUBROUTINE CADS_Detect_Cloud_Heapsort
+
+SUBROUTINE CADS_Detect_Cloud_Smooth(KV,KW,PV,PVA)
+
+! This software was developed within the context of the EUMETSAT
+! Satellite Application Facility on Numerical Weather Prediction
+! (NWP SAF), under the Cooperation Agreement dated 7 December 2016,
+! between EUMETSAT and the Met Office, UK, by one or more partners
+! within the NWP SAF. The partners in the NWP SAF are the Met
+! Office, ECMWF, DWD and MeteoFrance.
+!
+! Copyright 2020, EUMETSAT, All Rights Reserved.
+
+! * CADS_Detect_Cloud_Smooth * - Boxcar-averaging in a REAL array
+! * Phil Watts ECMWF 24/01/02
+
+! * PURPOSE *
+! -----------
+! Calculate the moving average (smoothing filter) of array
+! No error checking supplied.
+
+! * INTERFACE *
+! -------------
+! *CALL* * CADS_Detect_Cloud_Smooth( )* (from CADS_Detect_Cloud)
+! WHERE KV : Number of elements in V
+! KW : Window width for filter
+! PV : Input array to be averaged
+! PVA : Averaged array
+
+! * MODIFICATIONS *
+! -----------------
+! 01/02/06 A.Collard 1.0 Original export version.
+! 13/01/15 R.Eresmaa 2.1 Make array size specifications implicit.
+! 05/02/19 R.Eresmaa 2.4 Explicit KIND specifications.
+! 16/04/20 R.Eresmaa 3.0 Rename and tidy up.
+
+ use kinds, only: i_kind, r_kind
+ IMPLICIT NONE
+
+!* 0.1 global variables
+ INTEGER(i_kind), INTENT(IN) :: KV ! length of V
+ INTEGER(i_kind), INTENT(IN) :: KW ! length of averaging window
+ REAL(r_kind), INTENT(IN) :: PV(:) ! original array
+ REAL(r_kind), INTENT(INOUT) :: PVA(:) ! averaged array
+
+!* 0.2 local variables
+ INTEGER(i_kind) :: INJ,J,I
+
+ PVA(:)=0.0_r_kind
+
+ DO I = 1,KV ! loop over array elements
+ INJ=0
+ DO J=I-KW/2,I+KW/2,1 ! loop over window
+ IF (J > 0 .AND. J < (KV+1)) THEN ! if window element exists in
+ ! original array
+ INJ=INJ+1
+ PVA(I)=PVA(I)+PV(J) ! add value
+ ENDIF
+ ENDDO
+ PVA(I)=PVA(I)/REAL(INJ) ! mean value
+ ENDDO
+
+END SUBROUTINE CADS_Detect_Cloud_Smooth
+
+SUBROUTINE CADS_Detect_Cloud_Scenario( K__Sensor, K__Band, K__NumChans, K__GradChkInterval, K__Index, K__Chan_High, &
+ K__Chan_Low, K__Chan_Windows, K__Imager_Flag, K__Scen_Index, K__Start_Channel, P__DBT)
+
+! This software was developed within the context of the EUMETSAT
+! Satellite Application Facility on Numerical Weather Prediction
+! (NWP SAF), under the Cooperation Agreement dated 7 December 2016,
+! between EUMETSAT and the Met Office, UK, by one or more partners
+! within the NWP SAF. The partners in the NWP SAF are the Met
+! Office, ECMWF, DWD and MeteoFrance.
+!
+! Copyright 2020, EUMETSAT, All Rights Reserved.
+
+! * CADS_Detect_Cloud_Scenario *
+! PHIL WATTS ECMWF 21/01/02
+
+! * PURPOSE *
+! -----------
+! Determine which of the three possible scenarios best describes
+! the input data.
+! Quick Exit - no cloud in the FOV
+! Warm Start - warm cloud above relatively colder surface
+! Cold Start - cold cloud above relatively warmer surface (most common)
+
+! * INTERFACE *
+! -------------
+! * CALL* * CADS_Detect_Cloud_Scenario( )* (from CADS_Detect_Cloud)
+! WHERE K__Sensor : Satellite sensor (AIRS/IASI/CrIS)
+! K__Band : Band number
+! K__NumChans : Number of channels in this band
+! K__GradChkInterval : Gradient-checking interval
+! K__Index : Ranking index for the input dBT signal
+! K__Chan_High : High channel considered in initial minimum search
+! K__Chan_Low : Low channel considered in initial minimum search
+! K__Chan_Windows : Two channels defining longwave window
+! K__Imager_Flag : Input flag from collocated imager data
+! K__Scen_Index : Choice of cloud detection scenario (1, 2, or 3)
+! K__Start_Channel : Channel index for the start of final search
+! P__DBT : Input dBT signal
+
+! * MODIFICATIONS *
+! -----------------
+! 03/02/06 A.Collard 1.0 Tidy up in preparation for IASI
+! 03/05/06 A.Collard 1.0.1 Band size is now passed in (allows for
+! missing channels).
+! 04/05/06 A.Collard 1.0.2 The index of the first cloudy channel is now
+! returned to allow cross-band cloud detection
+! 16/02/07 A.Collard 1.0.3 Change to the padding to allow the bottom
+! channel to be flagged as clear in a
+! non-quickstart situation.
+! 16/01/09 A.Collard 1.1 Gradient check on quick exit
+! Start channel for cold start moved to highest
+! channel where BT threshold exceeded
+! 11/11/11 R.Eresmaa 1,2 Index of the lowest clear channel added to
+! the output parameters.
+! Change of the starting channel is no longer
+! allowed in cases where gradient > -threshold.
+! 04/12/13 R.Eresmaa 2.0 Allow quick exit only if collocated imager
+! data supports hypothesis of a clear FOV
+! 13/01/15 R.Eresmaa 2.1 Remove the need to create temporary array in
+! the call to MOVINGA.
+! the call to MOVINGA.
+! 04/02/19 R.Eresmaa 2.4 Explicit KIND specifications.
+! 16/04/20 R.Eresmaa 3.0 Divide the previous CF_Digital in two:
+! Cloud_Scenario (here) and Cloud_Separator.
+
+
+ use kinds, only: i_kind, r_kind
+ IMPLICIT NONE
+
+!* 0.1 Global arrays
+ INTEGER(i_kind), INTENT(IN) :: K__SENSOR ! Sensor
+ INTEGER(i_kind), INTENT(IN) :: K__Band ! Band number
+ INTEGER(i_kind), INTENT(IN) :: K__NumChans ! Number of usable channels in band
+ INTEGER(i_kind), INTENT(IN) :: K__GradChkInterval ! Gradient-check interval
+ INTEGER(i_kind), INTENT(IN) :: K__INDEX(:) ! Ranking index for dBT
+ INTEGER(i_kind), INTENT(IN) :: K__Chan_High ! First channel clear of high stratospheric model errors
+ INTEGER(i_kind), INTENT(IN) :: K__Chan_Low ! Last channel clear of PBL humidity errors
+ INTEGER(i_kind), INTENT(IN) :: K__Chan_Windows(2) ! Two channels defining long-wave window bounds
+ INTEGER(i_kind), INTENT(IN) :: K__Imager_Flag ! Input imager cloud flag
+ INTEGER(i_kind), INTENT(OUT) :: K__Scen_Index ! Choice of scenario
+ INTEGER(i_kind), INTENT(OUT) :: K__Start_Channel ! Final starting channel
+ REAL(r_kind), INTENT(IN) :: P__DBT(:) ! Input ranked-smoothed dBT signal
+
+! Local variables
+ REAL(r_kind), ALLOCATABLE :: Z__DBT_w_Buffer(:) ! Smoothed-ranked DBT
+ INTEGER(i_kind) :: I__Buffer ! No. of buffer channels
+ INTEGER(i_kind) :: I__Start_Channel ! Primary starting channel for cloud search
+ INTEGER(i_kind) :: I__Start_Channel_Surf ! Secondary starting channel for cloud search
+ INTEGER(i_kind) :: I__Max_Channel ! Channel corresponding to maximum of the smoothed dBT
+ INTEGER(i_kind) :: JCH,JMIN(1),JMAX(1),I
+
+ LOGICAL :: LLCOLD, LL__WINDOW_GRAD_CHECK, LL__StartChannelChanged
+ LOGICAL :: LL__Search_for_Cloud_Top
+
+! These carry the values in S__CADS_Setup_Cloud
+ REAL(r_kind) :: Z__BT_Threshold ! Solution contaminated threshold
+ REAL(r_kind) :: Z__Grad_Threshold ! Gradient threshold at which to stop filter procession
+ REAL(r_kind) :: Z__Window_Grad_Threshold ! Gradient threshold for window check
+
+
+!=============================================================================
+
+
+ Z__BT_Threshold = &
+ S__CADS_Setup_Cloud(K__SENSOR) % R__BT_Threshold(K__Band)
+ Z__Grad_Threshold = &
+ S__CADS_Setup_Cloud(K__SENSOR) % R__Grad_Threshold(K__Band)
+ Z__Window_Grad_Threshold = &
+ S__CADS_Setup_Cloud(K__SENSOR) % R__Window_Grad_Threshold(K__Band)
+
+
+!1. Include buffer channels at the start and end of the input smoothed
+! departure array
+
+ I__BUFFER = K__GradChkInterval
+ ALLOCATE(Z__DBT_w_Buffer(-I__Buffer+1:K__NumChans+1))
+
+ Z__DBT_w_Buffer(1:K__NumChans) = P__DBT(:)
+ Z__DBT_w_Buffer(-I__BUFFER+1:0) = Z__DBT_w_Buffer(1)
+ Z__DBT_w_Buffer(K__NumChans+1) = Z__DBT_w_Buffer(K__NumChans)
+
+
+!2. Prepare for the cloud search
+
+! First define a set of key channels
+
+ JMIN=MINLOC(Z__DBT_w_Buffer(K__Chan_High:K__NumChans))
+ I__Start_Channel_Surf = K__Chan_High+JMIN(1)-1
+
+ JMIN=MINLOC(Z__DBT_w_Buffer(K__Chan_High:K__Chan_Low))
+ I__Start_Channel = K__Chan_High+JMIN(1)-1
+
+! Look for highest channel with DBT<-BT_Threshold and move I__Start_Channel
+! there if higher than current I__Start_Channel:
+ JCH = I__Start_Channel
+ StartChanLoop : DO I=K__Chan_High,K__NumChans
+ IF (Z__DBT_w_Buffer(I) < -Z__BT_Threshold .OR. I == I__Start_Channel) THEN
+ JCH = I
+ Exit StartChanLoop
+ ENDIF
+ ENDDO StartChanLoop
+ I__Start_Channel = JCH
+
+! Do the same with I__Start_Channel_Surf
+ JCH = I__Start_Channel_Surf
+ StartChanLoop_Surf : DO I=K__Chan_High,K__NumChans
+ IF (Z__DBT_w_Buffer(I) < -Z__BT_Threshold .OR. I == I__Start_Channel_Surf) THEN
+ JCH = I
+ Exit StartChanLoop_Surf
+ ENDIF
+ ENDDO StartChanLoop_Surf
+ I__Start_Channel_Surf = JCH
+
+! Find the position of the equivalent maximum departure (for quick exit test)
+ JMAX=MAXLOC(Z__DBT_w_Buffer(K__Chan_High:K__NumChans))
+ I__Max_Channel = K__Chan_High+JMAX(1)-1
+
+! Long-wave window gradient check
+ LL__WINDOW_GRAD_CHECK=.TRUE.
+ IF (ALL(K__Chan_Windows > 0)) LL__WINDOW_GRAD_CHECK = &
+ (ABS(Z__DBT_w_Buffer(K__INDEX(K__Chan_Windows(1))) - &
+ Z__DBT_w_Buffer(K__INDEX(K__Chan_Windows(2)))) &
+ < Z__Window_Grad_Threshold)
+
+! Choose scenario to be followed
+ LL__Search_for_Cloud_Top=.TRUE.
+ IF (ABS(Z__DBT_w_Buffer(I__Start_Channel_Surf)) < Z__BT_Threshold .AND. &
+ ABS(Z__DBT_w_Buffer(I__Start_Channel)) < Z__BT_Threshold .AND. &
+ ABS(Z__DBT_w_Buffer(I__Max_Channel)) < Z__BT_Threshold .AND. &
+ ABS(Z__DBT_w_Buffer(K__NumChans)) < Z__BT_Threshold .AND. &
+ LL__WINDOW_GRAD_CHECK .AND. &
+ K__Imager_Flag==0 .AND. &
+ S__CADS_Setup_Cloud(K__SENSOR) % L__Do_Quick_Exit) THEN
+ !Quick exit
+ LL__Search_for_Cloud_Top=.FALSE.
+ ELSEIF (ABS(Z__DBT_w_Buffer(I__Start_Channel)) < Z__BT_Threshold .AND. &
+ Z__DBT_w_Buffer(K__NumChans) > Z__BT_Threshold ) THEN
+ !Warm cloud start at next-to-bottom channel (allowing one channel for
+ !gradient calculations).
+ LLCOLD = .FALSE.
+ I__Start_Channel = K__NumChans-1
+ ELSEIF (Z__DBT_w_Buffer(I__Start_Channel) < -Z__BT_Threshold ) THEN
+ LLCOLD = .TRUE.
+ ELSEIF (Z__DBT_w_Buffer(I__Start_Channel) > Z__BT_Threshold ) THEN
+ LLCOLD = .FALSE.
+ ELSE
+ LLCOLD = .TRUE.
+ ENDIF
+
+ IF (LL__Search_for_Cloud_Top) THEN ! Either cold or warm start
+ ! (but not quick exit)
+
+ JCH=I__Start_Channel
+
+! Re-evaluate the choice of scenario:
+! If the primary starting channel appears clear, and the secondary
+! starting channel is lower, start from the latter. In that case
+! re-evaluate whether cold or warm start is more appropriate.
+ IF (I__Start_Channel /= I__Start_Channel_Surf) THEN
+
+ LL__StartChannelChanged = .FALSE.
+ IF (LLCOLD .AND. ( (Z__DBT_w_Buffer(JCH-1)-Z__DBT_w_Buffer(JCH+1)) < &
+ Z__Grad_Threshold .AND. &
+ Z__DBT_w_Buffer(JCH-K__GradChkInterval)-Z__DBT_w_Buffer(JCH+1) < &
+ Z__Grad_Threshold .AND. &
+ ABS(Z__DBT_w_Buffer(JCH)) < Z__BT_Threshold)) THEN
+ I__Start_Channel = I__Start_Channel_Surf
+ LL__StartChannelChanged = .TRUE.
+ ENDIF
+
+ IF (LL__StartChannelChanged) THEN
+
+ IF (ABS(Z__DBT_w_Buffer(I__Start_Channel)) < Z__BT_Threshold .AND. &
+ Z__DBT_w_Buffer(K__NumChans) > Z__BT_Threshold ) THEN
+ !Warm cloud start at next-to-bottom channel (allowing one channel for
+ !gradient calculations).
+ LLCOLD = .FALSE.
+ I__Start_Channel = K__NumChans-1
+ ELSEIF (Z__DBT_w_Buffer(I__Start_Channel) < -Z__BT_Threshold ) THEN
+ LLCOLD = .TRUE.
+ ELSEIF (Z__DBT_w_Buffer(I__Start_Channel) > Z__BT_Threshold ) THEN
+ LLCOLD = .FALSE.
+ ELSE
+ LLCOLD = .TRUE.
+ ENDIF
+ JCH = I__Start_Channel
+
+ ENDIF
+ ENDIF
+
+ IF (LLCOLD) THEN
+ K__Scen_Index=3
+ ELSE
+ K__Scen_Index=2
+ ENDIF
+ K__Start_Channel = JCH
+
+ ELSE
+
+ K__Scen_Index=1
+ K__Start_Channel=0
+
+ ENDIF ! Search for cloud top
+
+ IF (ALLOCATED(Z__DBT_w_Buffer)) DEALLOCATE(Z__DBT_w_Buffer)
+
+END SUBROUTINE CADS_Detect_Cloud_Scenario
+
+SUBROUTINE CADS_Detect_Cloud_Separator( K__Sensor, K__Band, K__NumChans, K__GradChkInterval, K__Index, K__Cloud_Flag, &
+ K__Cloud_Level, K__Clear_Level, K__Scen_Index, K__Start_Channel, P__DBT)
+
+! This software was developed within the context of the EUMETSAT
+! Satellite Application Facility on Numerical Weather Prediction
+! (NWP SAF), under the Cooperation Agreement dated 7 December 2016,
+! between EUMETSAT and the Met Office, UK, by one or more partners
+! within the NWP SAF. The partners in the NWP SAF are the Met
+! Office, ECMWF, DWD and MeteoFrance.
+!
+! Copyright 2020, EUMETSAT, All Rights Reserved.
+
+! * CADS_Detect_Cloud_Separator *
+! PHIL WATTS ECMWF 21/01/02
+
+! * PURPOSE *
+! -----------
+! Along the vertically-ranked and smoothed array of departures, find
+! the separating point at which all cloud-affected channels are on
+! one side and all clear channels are on the other side.
+
+! * INTERFACE *
+! ------------
+! * CALL* * CADS_Detect_Cloud_Separator( )* (from CADS_Detect_Cloud)
+! WHERE K__Sensor : Satellite sensor (AIRS/IASI/CrIS)
+! K__Band : Band number
+! K__NumChans : Number of channels in this band
+! K__GradChkInterval : Gradient-checking interval
+! K__Index : Ranking index for the input dBT signal
+! K__Cloud_Flag : Cloud flag by channel; 0=clear, 1=cloudy
+! K__Cloud_Level : Index of the highest cloud-contaminated channel
+! K__Clear_Level : Index of the lowest clear channel
+! K__Scen_Index : Choice of cloud detection scenario (1, 2, or 3)
+! K__Start_Channel : Starting channel for the cloud search
+! P__DBT : Input dBT signal
+
+! MODIFICATIONS
+! 03/02/06 A.Collard 1.0 Tidy up in preparation for IASI
+! 03/05/06 A.Collard 1.0.1 Band size is now passed in (allows for
+! missing channels).
+! 04/05/06 A.Collard 1.0.2 The index of the first cloudy channel is now
+! returned to allow cross-band cloud detection
+! 16/02/07 A.Collard 1.0.3 Change to the padding to allow the bottom
+! channel to be flagged as clear in a
+! non-quickstart situation.
+! 16/01/09 A.Collard 1.1 Gradient check on quick exit
+! Start channel for cold start moved to highest
+! channel where BT threshold exceeded
+! 11/11/11 R.Eresmaa 1,2 Index of the lowest clear channel added to
+! the output parameters.
+! Change of the starting channel is no longer
+! allowed in cases where gradient > -threshold.
+! 04/12/13 R.Eresmaa 2.0 Allow quick exit only if collocated imager
+! data supports hypothesis of a clear FOV
+! 13/01/15 R.Eresmaa 2.1 Remove the need to create temporary array in
+! the call to MOVINGA.
+! 04/02/19 R.Eresmaa 2.4 Explicit KIND specifications.
+! 16/04/20 R.Eresmaa 3.0 Divide the previous CF_Digital in two:
+! Cloud_Scenario and Cloud_Separator (here).
+
+ use kinds, only: i_kind, r_kind
+ IMPLICIT NONE
+
+!* 0.1 Global arrays
+ INTEGER(i_kind), INTENT(IN ) :: K__SENSOR ! Sensor
+ INTEGER(i_kind), INTENT(IN ) :: K__Band ! Band number
+ INTEGER(i_kind), INTENT(IN ) :: K__NumChans ! Number of usable channels in band
+ INTEGER(i_kind), INTENT(IN ) :: K__GradChkInterval ! Gradient-check interval
+ INTEGER(i_kind), INTENT(IN ) :: K__INDEX(:) ! Ranking index for dBT
+ INTEGER(i_kind), INTENT(INOUT) :: K__Cloud_Flag(:) ! Cloud flags
+ INTEGER(i_kind), INTENT( OUT) :: K__Cloud_Level ! Index of highest cloudy channel
+ INTEGER(i_kind), INTENT( OUT) :: K__Clear_Level ! Index of lowest clear channel
+ INTEGER(i_kind), INTENT(IN ) :: K__Scen_Index ! Choice of scenario
+ INTEGER(i_kind), INTENT(IN ) :: K__Start_Channel ! Choice of scenario
+ REAL(r_kind), INTENT(IN ) :: P__DBT(:) ! Input ranked dBT signal
+
+
+! Local variables
+ REAL(r_kind), ALLOCATABLE :: Z__DBT_w_Buffer(:) ! Smoothed-ranked DBT
+ INTEGER(i_kind) :: I__Buffer ! No. of buffer channels
+ INTEGER(i_kind) :: JCH
+
+! These carry the values in S__CADS_Setup_Cloud
+ REAL(r_kind) :: Z__BT_Threshold ! Solution contaminated threshold
+ REAL(r_kind) :: Z__Grad_Threshold ! Gradient threshold at which to stop
+ ! filter procession
+
+!=============================================================================
+
+
+ Z__BT_Threshold = &
+ S__CADS_Setup_Cloud(K__SENSOR) % R__BT_Threshold(K__Band)
+ Z__Grad_Threshold = &
+ S__CADS_Setup_Cloud(K__SENSOR) % R__Grad_Threshold(K__Band)
+
+ K__Cloud_Flag(:)=1
+
+!1. Include buffer channels at the start and end of the input smoothed
+! departure array
+
+ I__BUFFER = K__GradChkInterval
+ ALLOCATE(Z__DBT_w_Buffer(-I__Buffer+1:K__NumChans+1))
+
+ Z__DBT_w_Buffer(1:K__NumChans) = P__DBT(:)
+ Z__DBT_w_Buffer(-I__BUFFER+1:0) = Z__DBT_w_Buffer(1)
+ Z__DBT_w_Buffer(K__NumChans+1) = Z__DBT_w_Buffer(K__NumChans)
+
+
+!2. Search for the lowest non-contaminated channel
+
+ JCH = K__Start_Channel
+
+ SELECT CASE (K__Scen_Index)
+
+ CASE (1) ! Quick Exit
+ K__Cloud_Level = 0
+
+ CASE (2) ! Warm Start
+! In the case of Warm Start, progress towards higher channels whilst
+! -ve difference is decreasing
+ DO WHILE ( ((Z__DBT_w_Buffer(JCH-1)-Z__DBT_w_Buffer(JCH+1)) < &
+ -1.0_r_kind * Z__Grad_Threshold .OR. &
+ (Z__DBT_w_Buffer(JCH-K__GradChkInterval)-Z__DBT_w_Buffer(JCH+1)) < &
+ -1.0_r_kind * Z__Grad_Threshold .OR. &
+ ABS(Z__DBT_w_Buffer(JCH)) > Z__BT_Threshold) .AND. JCH > 1 )
+ JCH = JCH-1
+ ENDDO
+ K__Cloud_Level = JCH
+
+ CASE (3) ! Cold Start
+! In the case of Cold Start, progress towards higher channels whilst
+! -ve difference is decreasing
+ DO WHILE (( (Z__DBT_w_Buffer(JCH-1)-Z__DBT_w_Buffer(JCH+1)) > &
+ Z__Grad_Threshold .OR. &
+ (Z__DBT_w_Buffer(JCH-K__GradChkInterval)-Z__DBT_w_Buffer(JCH+1)) > &
+ Z__Grad_Threshold .OR. &
+ ABS(Z__DBT_w_Buffer(JCH)) > Z__BT_Threshold) .AND. JCH > 1 )
+ JCH = JCH-1
+ ENDDO
+ K__Cloud_Level = JCH
+
+ CASE DEFAULT
+ RETURN
+
+ END SELECT
+
+!3. Output channel indices for the highest cloud and lowest clear levels
+ IF (K__Cloud_Level > 1) THEN
+ K__Cloud_Flag(K__INDEX(1:K__Cloud_Level-1))=0
+ K__Clear_Level=K__INDEX(K__Cloud_Level-1)
+ K__Cloud_Level=K__INDEX(K__Cloud_Level)
+ ELSEIF (K__Cloud_Level>0) THEN
+ K__Clear_Level=K__INDEX(K__Cloud_Level)
+ K__Cloud_Level=K__INDEX(K__Cloud_Level)
+ ELSE
+ K__Cloud_Flag(:)=0
+ ENDIF
+
+ IF (ALLOCATED(Z__DBT_w_Buffer)) DEALLOCATE(Z__DBT_w_Buffer)
+
+END SUBROUTINE CADS_Detect_Cloud_Separator
+
+subroutine cads_imager_calc(obstype,isis,nobs,nreal,nchanl,nsig,data_s,init_pass,mype, &
+ imager_cluster_fraction,imager_cluster_bt,imager_chan_stdev, imager_model_bt)
+
+!$$$ subprogram documentation block
+!
+! subprogram: cads_imager_calc compute model equivalent to the imager channels used by CADS
+! prgmmr: Jung
+!
+! abstract: accumulate the data necessary to derive the model equivalent brightness temperatures
+! used by the cloud and aerosol detection software for the imager cloud tests.
+!
+! program history log:
+!
+!
+!
+! subroutines included:
+!
+!
+! input argument list:
+!
+! obstype - type of tb observation
+! isis - sensor/instrument/satellite id
+! nobs - number of observations
+! nreal - number of pieces of info (location, time, etc) per obs
+! nchanl - number of channels per obs
+! nsig - number of model layers
+! data_s - array containing input data information for a specific sensor
+! init_pass - state of "setup" processing
+! mype - mpi task id
+!
+! output argument list:
+
+! imager_cluster_fraction - CADS cluster fraction ( dimension 7)
+! imager_cluster_bt - avreage brightness temperature of a cluster
+! imager_chan stdev - brightness temperature standard deviation of the cluster
+! imager_model_bt - model derived brightness temperature
+!
+!
+!$$$ end documentation block
+
+ use kinds, only: i_kind, r_kind
+ use constants, only: zero
+ use radiance_mod, only: rad_obs_type
+ use radinfo, only: jpch_rad, nusis, crtm_coeffs_path, nsigradjac
+ use crtm_interface, only: init_crtm, call_crtm, destroy_crtm, itime
+ use obsmod, only: dval_use
+ use gsi_nstcouplermod, only: nstinfo
+
+ implicit none
+
+ logical, intent(in) :: init_pass
+ character(len=10), intent(in) :: obstype
+ character(len=20), intent(in) :: isis
+ integer(i_kind), intent(in) :: nobs, nreal, nchanl, nsig
+ integer(i_kind), intent(in) :: mype
+ real(r_kind),dimension(nreal+nchanl,nobs),intent(in) :: data_s
+ real(r_kind),dimension(7,nobs), intent(out) :: imager_cluster_fraction
+ real(r_kind),dimension(2,7,nobs), intent(out) :: imager_cluster_bt
+ real(r_kind),dimension(2,nobs), intent(out) :: imager_chan_stdev, imager_model_bt
+
+! local variables
+ integer(i_kind) :: jc, i, n
+ integer(i_kind) :: itmp1_cads, itmp2_cads, nchanl_cads, maxinfo, dval_info, cads_info, error_status
+ integer(i_kind),allocatable,dimension(:) :: ich_cads
+ logical :: imager_spccoeff, imager_taucoeff
+ real(r_kind) :: dtime, clw_guess, ciw_guess, rain_guess, snow_guess
+ real(r_kind) :: trop5, tzbgr, dtsavg, sfc_speed
+ real(r_kind),dimension(nsig) :: qvp, tvp, qs, prsltmp
+ real(r_kind),dimension(nsig+1) :: prsitmp
+ real(r_kind),allocatable,dimension(:) :: tsim_cads, emissivity_cads, chan_level_cads
+ real(r_kind),allocatable,dimension(:) :: ts_cads, emissivity_k_cads,data_s_cads
+ real(r_kind),allocatable,dimension(:,:) :: ptau5_cads, temp_cads, wmix_cads, jacobian_cads
+ character(len=80) :: spc_filename, tau_filename
+ character(len=20) :: isis_cads
+ character(len=10) :: obstype_cads
+
+ type(rad_obs_type) :: radmod
+
+ cads_info = 23
+ dval_info = 0
+ if (dval_use) dval_info = 2
+
+ itmp1_cads = len(trim(obstype))
+ itmp2_cads = len(trim(isis))
+
+ if ( obstype == 'iasi' ) then
+ isis_cads = 'avhrr3'//isis(itmp1_cads+1:itmp2_cads)
+ obstype_cads = 'avhrr'
+! nchanl_cads = 3 !channels 3 - 5
+ elseif ( obstype == 'cris' .or. obstype == 'cris-fsr' ) then
+! isis_cads = 'viirs-m'//isis(itmp1+1:itmp2) When naming convention becomes standarized with CrIS
+ if ( isis == 'cris-fsr_npp' .or. isis == 'cris_npp' ) then
+ isis_cads = 'viirs-m_npp'
+ elseif ( isis == 'cris-fsr_n20' ) then
+ isis_cads = 'viirs-m_n20'
+ spc_filename = trim(crtm_coeffs_path)//trim(isis_cads)//'.SpcCoeff.bin'
+ inquire(file=trim(spc_filename), exist=imager_spccoeff)
+ if ( .not. imager_spccoeff ) isis_cads = 'viirs-m_j1'
+ elseif ( isis == 'cris-fsr_n21' ) then
+ isis_cads = 'viirs-m_n21'
+ spc_filename = trim(crtm_coeffs_path)//trim(isis_cads)//'.SpcCoeff.bin'
+ inquire(file=trim(spc_filename), exist=imager_spccoeff)
+ if ( .not. imager_spccoeff ) isis_cads = 'viirs-m_j2'
+ endif
+ obstype_cads = 'viirs-m'
+! nchanl_cads = 5 ! channels 12 - 16
+ endif
+
+ spc_filename = trim(crtm_coeffs_path)//trim(isis_cads)//'.SpcCoeff.bin'
+ inquire(file=trim(spc_filename), exist=imager_spccoeff)
+ tau_filename = trim(crtm_coeffs_path)//trim(isis_cads)//'.TauCoeff.bin'
+ inquire(file=trim(tau_filename), exist=imager_taucoeff)
+
+! IF the RTM files exist allocate and setup various arrays for the RTM
+ if ( imager_spccoeff .and. imager_taucoeff) then
+ nchanl_cads = 0
+ do i=1,jpch_rad
+ if (trim(isis_cads) == nusis(i)) then
+ nchanl_cads = nchanl_cads +1
+ endif
+ end do
+
+ allocate( ich_cads(nchanl_cads) )
+ jc = 0
+ do i=1,jpch_rad
+ if (trim(isis_cads) == nusis(i)) then
+ jc = jc +1
+ ich_cads(jc) = i
+ endif
+ end do
+
+ call init_crtm(init_pass,-99,mype,nchanl_cads,nreal,isis_cads,obstype_cads,radmod)
+
+! Initialize variables needed for the infrared cloud and aerosol detection software
+ allocate(data_s_cads(nreal+nchanl_cads),tsim_cads(nchanl_cads),emissivity_cads(nchanl_cads), &
+ chan_level_cads(nchanl_cads),ptau5_cads(nsig,nchanl_cads),ts_cads(nchanl_cads),emissivity_k_cads(nchanl_cads), &
+ temp_cads(nsig,nchanl_cads),wmix_cads(nsig,nchanl_cads), jacobian_cads(nsigradjac,nchanl_cads))
+
+ do n = 1,nobs ! loop to derive imager BTs for CADS
+! Extract analysis relative observation time.
+ dtime = data_s(itime,n)
+ maxinfo = nreal - cads_info - dval_info - nstinfo
+ if ( sum(data_s(maxinfo+1:maxinfo+7,n)) > 0.90_r_kind ) then ! imager cluster information exists for this profile
+ data_s_cads = data_s(1:nreal+nchanl_cads,n)
+ call call_crtm(obstype_cads,dtime,data_s_cads,nchanl_cads,nreal,ich_cads, &
+ tvp,qvp,qs,clw_guess,ciw_guess,rain_guess,snow_guess,prsltmp,prsitmp, &
+ trop5,tzbgr,dtsavg,sfc_speed,tsim_cads,emissivity_cads,chan_level_cads, &
+ ptau5_cads,ts_cads,emissivity_k_cads,temp_cads,wmix_cads,jacobian_cads,error_status)
+
+! Transfer imager data to arrays for qc_irsnd
+ imager_cluster_fraction(1:7,n) = data_s(maxinfo+1:maxinfo+7,n)
+ imager_cluster_bt(1,1:7,n) = data_s(maxinfo+8:maxinfo+14,n)
+ imager_cluster_bt(2,1:7,n) = data_s(maxinfo+15:maxinfo+21,n)
+ imager_chan_stdev(1:2,n) = data_s(maxinfo+22:maxinfo+23,n)
+ imager_model_bt(1:2,n) = tsim_cads(nchanl_cads-1:nchanl_cads)
+ endif ! imager information exists
+ end do ! End loop to derive imager BTs
+
+ call destroy_crtm
+ deallocate(data_s_cads,tsim_cads,emissivity_cads, ich_cads,chan_level_cads,ptau5_cads,&
+ ts_cads,emissivity_k_cads, temp_cads,wmix_cads, jacobian_cads)
+ endif ! RTM files exist
+
+ end subroutine cads_imager_calc
+
+end module cads
diff --git a/src/gsi/calc_fov_crosstrk.f90 b/src/gsi/calc_fov_crosstrk.f90
index 75fffb1087..6cb817b56b 100644
--- a/src/gsi/calc_fov_crosstrk.f90
+++ b/src/gsi/calc_fov_crosstrk.f90
@@ -812,7 +812,7 @@ subroutine instrument_init(instr, satid, expansion, valid)
allocate (eccen(1:maxfov(instr)))
do i = 1, npoly
- psi(i) = two*pi*float(i-1)/float(npoly-1) ! Will connect Npoly points
+ psi(i) = two*pi*real(i-1,r_kind)/real(npoly-1,r_kind) ! Will connect Npoly points
enddo
! Precompute angles and sizes for speed. For accurate representation of fov,
@@ -1287,7 +1287,7 @@ subroutine get_sat_height(satid, height, valid)
height=866._r_kind
case('npp')
height=840._r_kind
- case('n20')
+ case('n20', 'n21', 'n22', 'n23')
height=840._r_kind
case default
write(6,*) 'GET_SAT_HEIGHT: ERROR, unrecognized satellite id: ', trim(satid)
diff --git a/src/gsi/calctends.f90 b/src/gsi/calctends.f90
index 4bd2c64e24..c6c58e9f4c 100644
--- a/src/gsi/calctends.f90
+++ b/src/gsi/calctends.f90
@@ -62,6 +62,7 @@ subroutine calctends(mype,teta,pri,guess,xderivative,yderivative,tendency)
use gsi_bundlemod, only: gsi_bundlegetpointer
use mpeu_util, only: die
+ use turblmod, only: use_pbl
implicit none
! Declare passed variables
@@ -357,7 +358,7 @@ subroutine calctends(mype,teta,pri,guess,xderivative,yderivative,tendency)
end do
end do !end do k
- call turbl(u,v,pri,t,teta,z,u_t,v_t,t_t,jtstart(kk),jtstop(kk))
+ if(use_pbl)call turbl(u,v,pri,t,teta,z,u_t,v_t,t_t,jtstart(kk),jtstop(kk))
if(.not.wrf_nmm_regional.and..not.nems_nmmb_regional)then
do k=1,nsig
diff --git a/src/gsi/calctends_ad.f90 b/src/gsi/calctends_ad.f90
index 72b5b76ffa..4f85a74485 100644
--- a/src/gsi/calctends_ad.f90
+++ b/src/gsi/calctends_ad.f90
@@ -67,6 +67,7 @@ subroutine calctends_ad(fields,fields_dt,mype)
use mpeu_util, only: die
use derivsmod, only: gsi_xderivative_bundle
use derivsmod, only: gsi_yderivative_bundle
+ use turblmod, only: use_pbl
implicit none
! Declare passed variables
@@ -356,7 +357,7 @@ subroutine calctends_ad(fields,fields_dt,mype)
end do
end if
- call turbl_ad(ges_prsi(1,1,1,it),ges_tv,ges_teta(1,1,1,it),&
+ if(use_pbl)call turbl_ad(ges_prsi(1,1,1,it),ges_tv,ges_teta(1,1,1,it),&
u,v,pri,t,u_t,v_t,t_t,jtstart(kk),jtstop(kk))
do k=nsig,1,-1
diff --git a/src/gsi/calctends_no_ad.f90 b/src/gsi/calctends_no_ad.f90
index e50f96df72..af792b69a5 100644
--- a/src/gsi/calctends_no_ad.f90
+++ b/src/gsi/calctends_no_ad.f90
@@ -72,6 +72,7 @@ subroutine calctends_no_ad(st,vp,t,p,mype,u_t,v_t,t_t,p_t,uvflag)
use gsi_bundlemod, only: gsi_bundlegetpointer
use derivsmod, only: gsi_xderivative_bundle
use derivsmod, only: gsi_yderivative_bundle
+ use turblmod, only: use_pbl
implicit none
! Declare passed variables
@@ -210,7 +211,7 @@ subroutine calctends_no_ad(st,vp,t,p,mype,u_t,v_t,t_t,p_t,uvflag)
end do
end if
- call turbl_ad(ges_prsi(1,1,1,it),ges_tv,ges_teta(1,1,1,it),&
+ if(use_pbl)call turbl_ad(ges_prsi(1,1,1,it),ges_tv,ges_teta(1,1,1,it),&
u,v,pri,t,u_t,v_t,t_t,jtstart(kk),jtstop(kk))
do k=nsig,1,-1
diff --git a/src/gsi/calctends_no_tl.f90 b/src/gsi/calctends_no_tl.f90
index 73be86be2e..c66a2abcc6 100644
--- a/src/gsi/calctends_no_tl.f90
+++ b/src/gsi/calctends_no_tl.f90
@@ -37,7 +37,7 @@ subroutine calctends_no_tl(st,vp,t,p,mype,u_t,v_t,t_t,p_t,uvflag)
! v - meridional wind on subdomain
! t - virtual temperature on subdomain
! mype - task id
-! uvflag - logical, set to true for st,vp wind components, instead of stream/potential function
+! uvflag - logical, set to true for u,v wind components, instead of stream/potential function
!
! output argument list:
! u_t - time tendency of u
@@ -64,6 +64,7 @@ subroutine calctends_no_tl(st,vp,t,p,mype,u_t,v_t,t_t,p_t,uvflag)
use gsi_bundlemod, only: gsi_bundlegetpointer
use derivsmod, only: gsi_xderivative_bundle
use derivsmod, only: gsi_yderivative_bundle
+ use turblmod, only: use_pbl
implicit none
! Declare passed variables
@@ -244,28 +245,21 @@ subroutine calctends_no_tl(st,vp,t,p,mype,u_t,v_t,t_t,p_t,uvflag)
end if
end if
-! top/bottom boundary condition:
do j=jtstart(kk),jtstop(kk)
do i=1,lat2
+
+! top/bottom boundary condition:
+
what(i,j,1)=zero
what(i,j,nsig+1)=zero
- enddo
- enddo
-
! load actual dp/dt
- do j=jtstart(kk),jtstop(kk)
- do i=1,lat2
p_t(i,j)=prsth(i,j,1)
- end do
- end do
! before big k loop, zero out the km1 summation arrays
- do j=jtstart(kk),jtstop(kk)
- do i=1,lat2
sumkm1 (i,j)=zero
sum2km1 (i,j)=zero
sumvkm1 (i,j)=zero
@@ -371,7 +365,7 @@ subroutine calctends_no_tl(st,vp,t,p,mype,u_t,v_t,t_t,p_t,uvflag)
end do !end do j
end do !end do k
- call turbl_tl(ges_prsi(1,1,1,it),ges_tv,ges_teta(1,1,1,it),&
+ if(use_pbl)call turbl_tl(ges_prsi(1,1,1,it),ges_tv,ges_teta(1,1,1,it),&
u,v,pri,t,u_t,v_t,t_t,jtstart(kk),jtstop(kk))
if(.not.wrf_nmm_regional.and..not.nems_nmmb_regional)then
diff --git a/src/gsi/calctends_tl.f90 b/src/gsi/calctends_tl.f90
index 59507fc6db..f5202f5f34 100644
--- a/src/gsi/calctends_tl.f90
+++ b/src/gsi/calctends_tl.f90
@@ -69,6 +69,7 @@ subroutine calctends_tl(fields,fields_dt,mype)
use mpeu_util, only: die, getindex
use derivsmod, only: gsi_xderivative_bundle
use derivsmod, only: gsi_yderivative_bundle
+ use turblmod, only: use_pbl
implicit none
! Declare passed variables
@@ -474,7 +475,7 @@ subroutine calctends_tl(fields,fields_dt,mype)
end do !end do j
end do !end do k
- call turbl_tl(ges_prsi(1,1,1,it),ges_tv,ges_teta(1,1,1,it),&
+ if(use_pbl)call turbl_tl(ges_prsi(1,1,1,it),ges_tv,ges_teta(1,1,1,it),&
u,v,pri,t,u_t,v_t,t_t,jtstart(kk),jtstop(kk))
if(.not.wrf_nmm_regional.and..not.nems_nmmb_regional)then
diff --git a/src/gsi/chemmod.f90 b/src/gsi/chemmod.f90
index 14a90c818c..06bfe6dce6 100644
--- a/src/gsi/chemmod.f90
+++ b/src/gsi/chemmod.f90
@@ -40,21 +40,23 @@ module chemmod
public :: naero_cmaq_fv3,aeronames_cmaq_fv3,imodes_cmaq_fv3
! fv3smoke
- public :: naero_smoke_fv3,aeronames_smoke_fv3,pm2_5_innov_threshold
+ public :: naero_smoke_fv3,aeronames_smoke_fv3
+ public :: pm2_5_innov_threshold,pm2_5_urban_innov_threshold,pm2_5_bg_threshold
+ public :: pm10_innov_threshold,pm10_urban_innov_threshold,pm10_bg_threshold,pm10_obs_threshold
public :: naero_gocart_wrf,aeronames_gocart_wrf
public :: pm2_5_guess,init_pm2_5_guess,&
aerotot_guess,init_aerotot_guess
public :: init_chem
- public :: berror_chem,berror_fv3_cmaq_regional,oneobtest_chem,maginnov_chem,magoberr_chem,oneob_type_chem,conconeobs
+ public :: berror_chem,berror_fv3_cmaq_regional,berror_fv3_sd_regional,oneobtest_chem,maginnov_chem,magoberr_chem,oneob_type_chem,conconeobs
public :: oblat_chem,oblon_chem,obpres_chem,diag_incr,oneobschem
public :: site_scale,nsites
public :: tunable_error
public :: in_fname,out_fname,incr_fname,maxstr
public :: code_pm25_ncbufr,code_pm25_anowbufr
public :: code_pm10_ncbufr,code_pm10_anowbufr
-
+ public :: anowbufr_ext
public :: l_aoderr_table
public :: laeroana_gocart,laeroana_fv3cmaq,laeroana_fv3smoke,crtm_aerosol_model,crtm_aerosolcoeff_format,crtm_aerosolcoeff_file, &
@@ -79,7 +81,8 @@ module chemmod
integer(i_kind) :: icvt_cmaq_fv3
real(r_kind) :: raod_radius_mean_scale,raod_radius_std_scale
real(r_kind) :: ppmv_conv = 96.06_r_kind/28.964_r_kind*1.0e+3_r_kind
- real(r_kind) :: pm2_5_innov_threshold
+ real(r_kind) :: pm2_5_innov_threshold,pm2_5_urban_innov_threshold,pm2_5_bg_threshold
+ real(r_kind) :: pm10_innov_threshold,pm10_urban_innov_threshold,pm10_bg_threshold,pm10_obs_threshold
logical :: wrf_pm2_5
@@ -90,7 +93,9 @@ module chemmod
logical :: aero_ratios
- logical :: oneobtest_chem,diag_incr,berror_chem,berror_fv3_cmaq_regional
+ logical :: oneobtest_chem,diag_incr,berror_chem
+ logical :: berror_fv3_cmaq_regional,berror_fv3_sd_regional
+ logical :: anowbufr_ext
character(len=max_varname_length) :: oneob_type_chem
integer(i_kind), parameter :: maxstr=256
real(r_kind) :: maginnov_chem,magoberr_chem,conconeobs,&
@@ -103,7 +108,7 @@ module chemmod
real(r_kind),parameter :: pm2_5_teom_max=900.0_r_kind !ug/m3
!some parameters need to be put here since convinfo file won't
!accomodate, stands for maximum realistic value of surface pm2.5
- real(r_kind),parameter :: pm10_teom_max=150.0_r_kind !ug/m3
+ real(r_kind),parameter :: pm10_teom_max=3000.0_r_kind !ug/m3
real(r_kind),parameter :: elev_missing=-9999.0_r_kind
@@ -157,10 +162,10 @@ module chemmod
'AOLGAJ', 'AISO1J', 'AISO2J', 'AISO3J', 'ATRP1J', 'ATRP2J',&
'ASQTJ', 'AOLGBJ', 'AORGCJ']
! fv3smoke
- integer(i_kind), parameter :: naero_smoke_fv3=2
+ integer(i_kind), parameter :: naero_smoke_fv3=3
character(len=max_varname_length), dimension(naero_smoke_fv3), parameter :: &
- aeronames_smoke_fv3=[character(len=max_varname_length) :: 'smoke','dust' ]
+ aeronames_smoke_fv3=[character(len=max_varname_length) :: 'smoke','dust','coarsepm']
! FV3CMAQ
integer(i_kind), parameter :: naero_cmaq_fv3=70 ! !number of cmaq aerosol species aero6
@@ -286,8 +291,15 @@ subroutine init_chem
!initialiazes default values to &CHEM namelist parameters
berror_chem=.false.
- berror_fv3_cmaq_regional=.false. ! Set .true. to use berror for fv3_cmaq_regional, whose cv has 10 characters
+ berror_fv3_cmaq_regional=.false. ! .False. : Dont perform aerosal DA for the online RRFS_CMAQ model so dont need to read in B for RRFS_CMAQ.
+ ! .true. : Use berror for fv3_cmaq_regional, whose cv has 10 characters
+ berror_fv3_sd_regional=.false. ! .False. : Dont perform aerosal DA for the RRFS_SD model so dont need to read in B for RRFS_SD.
+ ! .true. to use berror for rrfs_sd model, whose cv has 10 characters
oneobtest_chem=.false.
+ anowbufr_ext=.false. ! .False. : use default anowbufr data
+ ! .True. : use the extented bufr data
+ ! that includes PM10, station elevation
+ ! etal in addition to pm2.5.
maginnov_chem=30_r_kind
magoberr_chem=2_r_kind
oneob_type_chem='pm2_5'
@@ -307,9 +319,15 @@ subroutine init_chem
laeroana_gocart = .false.
laeroana_fv3cmaq = .false. ! .true. for performing aerosol analysis for regional FV3-CMAQ model(Please other parameters requred in gsimod.F90)
laeroana_fv3smoke = .false.
- pm2_5_innov_threshold = 20.0_r_kind
+ pm2_5_innov_threshold = 15.0_r_kind
+ pm2_5_urban_innov_threshold = 30.0_r_kind
+ pm2_5_bg_threshold = 2.0_r_kind
+ pm10_innov_threshold = 15.0_r_kind
+ pm10_urban_innov_threshold = 30.0_r_kind
+ pm10_bg_threshold = 2.0_r_kind
+ pm10_obs_threshold = 140.0_r_kind ! Barry's manuscript
l_aoderr_table = .false.
- icvt_cmaq_fv3 = 1 ! 1. Control variable is individual aerosol specie; 2: CV is total mass per I,J,K mode
+ icvt_cmaq_fv3 = 1 ! 1: Control variable is individual aerosol specie; 2: CV is total mass per I,J,K mode
raod_radius_mean_scale = 1.0_r_kind ! Tune radius of particles when calculating AOD using CRTM
raod_radius_std_scale = 1.0_r_kind ! Tune standard deviation of particles when calculating AOD using CRTM with CMAQ LUTs.
aod_qa_limit = 3
diff --git a/src/gsi/clw_mod.f90 b/src/gsi/clw_mod.f90
index 512aaded01..49387f05eb 100644
--- a/src/gsi/clw_mod.f90
+++ b/src/gsi/clw_mod.f90
@@ -2019,7 +2019,7 @@ subroutine gmi_37pol_diff(tb37v,tb37h,tsim37v,tsim37h,clw,ierrret)
clw = one - (tb37v-tb37h)/(tsim37v-tsim37h)
clw=max(zero,clw)
- if(tb37h > tb37v) then
+ if ((tb37h > tb37v) .or. (tb37h > 500_r_kind )) then
ierrret = 1
clw= r1000
endif
diff --git a/src/gsi/cmake/gsiapp_compiler_flags_Intel_Fortran.cmake b/src/gsi/cmake/gsiapp_compiler_flags_Intel_Fortran.cmake
index 8ba2887da8..b1d28132dc 100644
--- a/src/gsi/cmake/gsiapp_compiler_flags_Intel_Fortran.cmake
+++ b/src/gsi/cmake/gsiapp_compiler_flags_Intel_Fortran.cmake
@@ -14,7 +14,7 @@ set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -fp-model strict")
# DEBUG FLAGS
####################################################################
-set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -fp-model source -debug -ftrapuv -warn all,nointerfaces -check all,noarg_temp_created -fp-stack-check -fstack-protector")
+set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -init=snan,arrays -fp-model source -debug -ftrapuv -warn all,nointerfaces -check all,noarg_temp_created -fp-stack-check -fstack-protector")
####################################################################
# LINK FLAGS
diff --git a/src/gsi/compact_diffs.f90 b/src/gsi/compact_diffs.f90
index 14f7b8fdc5..0a65e9a515 100644
--- a/src/gsi/compact_diffs.f90
+++ b/src/gsi/compact_diffs.f90
@@ -268,7 +268,6 @@ subroutine stvp2uv(work,idim)
integer(i_kind) ix,iy
integer(i_kind) ny,i,j
real(r_kind) polsu,polnu,polnv,polsv
- real(r_kind),dimension(nlon):: grid3n,grid3s,grid1n,grid1s
real(r_kind),dimension(nlat-2,nlon):: a,b,grid1,grid2,grid3,grid4
if(idim <=1) write(6,*) ' error in call to stvp2uv ',idim
@@ -314,31 +313,21 @@ subroutine stvp2uv(work,idim)
polsu=polsu+grid3(1 ,ix)*coslon(ix)+grid1(1 ,ix)*sinlon(ix)
polsv=polsv+grid3(1 ,ix)*sinlon(ix)-grid1(1 ,ix)*coslon(ix)
end do
- polnu=polnu/float(nlon)
- polnv=polnv/float(nlon)
- polsu=polsu/float(nlon)
- polsv=polsv/float(nlon)
- do ix=1,nlon
- grid3n(ix)= polnu*coslon(ix)+polnv*sinlon(ix)
- grid1n(ix)=-polnu*sinlon(ix)+polnv*coslon(ix)
- grid3s(ix)= polsu*coslon(ix)+polsv*sinlon(ix)
- grid1s(ix)= polsu*sinlon(ix)-polsv*coslon(ix)
- end do
+ polnu=polnu/real(nlon,r_kind)
+ polnv=polnv/real(nlon,r_kind)
+ polsu=polsu/real(nlon,r_kind)
+ polsv=polsv/real(nlon,r_kind)
! work(1 is u, work(2 is v
do j=1,nlon
- do i=1,nlat
- if(i /= 1 .and. i /= nlat)then
- work(1,i,j)=grid3(i-1,j)
- work(2,i,j)=grid1(i-1,j)
- else if(i == 1)then
- work(1,i,j)=grid3s(j)
- work(2,i,j)=grid1s(j)
- else
- work(1,i,j)=grid3n(j)
- work(2,i,j)=grid1n(j)
- end if
+ do i=2,nlat-1
+ work(1,i,j)=grid3(i-1,j)
+ work(2,i,j)=grid1(i-1,j)
end do
- enddo
+ work(1,1,j)= polsu*coslon(j)+polsv*sinlon(j)
+ work(2,1,j)= polsu*sinlon(j)-polsv*coslon(j)
+ work(1,nlat,j)= polnu*coslon(j)+polnv*sinlon(j)
+ work(2,nlat,j)= -polnu*sinlon(j)+polnv*coslon(j)
+ end do
return
end subroutine stvp2uv
@@ -463,7 +452,7 @@ subroutine uv2vordiv(work1,work2)
vor_s = vor_s + grid_vor( 1,ix)
vor_n = vor_n + grid_vor(ny,ix)
end do
- rnlon = one/float(nlon)
+ rnlon = one/real(nlon,r_kind)
div_s = div_s*rnlon
div_n = div_n*rnlon
vor_s = vor_s*rnlon
@@ -749,18 +738,14 @@ subroutine tstvp2uv(work,idim)
ny=nlat-2
do j=1,nlon
- do i=1,nlat
- if(i /= 1 .and. i /= nlat)then
- grid3(i-1,j)=work(1,i,j)
- grid1(i-1,j)=work(2,i,j)
- else if(i == 1)then
- grid3s(j)=work(1,i,j)
- grid1s(j)=work(2,i,j)
- else
- grid3n(j)=work(1,i,j)
- grid1n(j)=work(2,i,j)
- end if
+ do i=2,nlat-1
+ grid3(i-1,j)=work(1,i,j)
+ grid1(i-1,j)=work(2,i,j)
end do
+ grid3s(j)=work(1,1,j)
+ grid1s(j)=work(2,1,j)
+ grid3n(j)=work(1,nlat,j)
+ grid1n(j)=work(2,nlat,j)
end do
polnu=zero
@@ -773,10 +758,10 @@ subroutine tstvp2uv(work,idim)
polnv=polnv+grid3n(ix)*sinlon(ix)+coslon(ix)*grid1n(ix)
polsv=polsv+grid3s(ix)*sinlon(ix)-coslon(ix)*grid1s(ix)
end do
- polnu=polnu/float(nlon)
- polsu=polsu/float(nlon)
- polnv=polnv/float(nlon)
- polsv=polsv/float(nlon)
+ polnu=polnu/real(nlon,r_kind)
+ polsu=polsu/real(nlon,r_kind)
+ polnv=polnv/real(nlon,r_kind)
+ polsv=polsv/real(nlon,r_kind)
do ix=1,nlon
grid3(ny,ix)=grid3(ny,ix)+polnu*coslon(ix)+polnv*sinlon(ix)
@@ -815,16 +800,15 @@ subroutine tstvp2uv(work,idim)
nlon,ny,noq)
!$omp end parallel sections
do j=1,nlon
- do i=1,nlat
- if(i /= 1 .and. i /= nlat)then
-! NOTE: Adjoint of first derivative is its negative
- work(1,i,j)=-(a(i-1,j)+d(i-1,j))
- work(2,i,j)=-(b(i-1,j)+c(i-1,j))
- else
- work(1,i,j)=zero
- work(2,i,j)=zero
- end if
+ do i=2,nlat-1
+! NOTE: Adjoint of first derivative is its negative
+ work(1,i,j)=-(a(i-1,j)+d(i-1,j))
+ work(2,i,j)=-(b(i-1,j)+c(i-1,j))
end do
+ work(1,1,j)=zero
+ work(2,1,j)=zero
+ work(1,nlat,j)=zero
+ work(2,nlat,j)=zero
end do
return
@@ -1373,9 +1357,9 @@ subroutine inisph(r,yor,tau,nx,ny)
! Load coefficient array
ri=one/r
pih=pi/two
- pi2onx=pi/float(nxh)
+ pi2onx=pi/real(nxh,r_kind)
do ix=1,nxh
- coef(lacoy1+ix-1)=(float(ix)-half)*pi2onx
+ coef(lacoy1+ix-1)=(real(ix,r_kind)-half)*pi2onx
enddo
call cdcoef(nxh,noq,zero,pi,coef(lacoy1),w&
@@ -1996,10 +1980,10 @@ subroutine compact_dlon(b,dbdx,vector)
polsu=polsu+grid3(1 ,ix)*coslon(ix)
polsv=polsv+grid3(1 ,ix)*sinlon(ix)
end do
- polnu=two*polnu/float(nlon)
- polnv=two*polnv/float(nlon)
- polsu=two*polsu/float(nlon)
- polsv=two*polsv/float(nlon)
+ polnu=two*polnu/real(nlon,r_kind)
+ polnv=two*polnv/real(nlon,r_kind)
+ polsu=two*polsu/real(nlon,r_kind)
+ polsv=two*polsv/real(nlon,r_kind)
do ix=1,nlon
grid3n(ix)= polnu*coslon(ix)+polnv*sinlon(ix)
grid3s(ix)= polsu*coslon(ix)+polsv*sinlon(ix)
@@ -2089,10 +2073,10 @@ subroutine tcompact_dlon(b,dbdx,vector)
polsu=polsu+coslon(ix)*grid3s(ix)
polsv=polsv+sinlon(ix)*grid3s(ix)
end do
- polnu=two*polnu/float(nlon)
- polnv=two*polnv/float(nlon)
- polsu=two*polsu/float(nlon)
- polsv=two*polsv/float(nlon)
+ polnu=two*polnu/real(nlon,r_kind)
+ polnv=two*polnv/real(nlon,r_kind)
+ polsu=two*polsu/real(nlon,r_kind)
+ polsv=two*polsv/real(nlon,r_kind)
do ix=1,nlon
grid3(ny,ix)=grid3(ny,ix)+coslon(ix)*polnu+sinlon(ix)*polnv
grid3(1 ,ix)=grid3(1 ,ix)+coslon(ix)*polsu+sinlon(ix)*polsv
@@ -2230,10 +2214,10 @@ subroutine compact_dlat(b,dbdy,vector)
polsu=polsu+grid4(1 ,ix)*sinlon(ix)
polsv=polsv-grid4(1 ,ix)*coslon(ix)
end do
- polnu=two*polnu/float(nlon)
- polnv=two*polnv/float(nlon)
- polsu=two*polsu/float(nlon)
- polsv=two*polsv/float(nlon)
+ polnu=two*polnu/real(nlon,r_kind)
+ polnv=two*polnv/real(nlon,r_kind)
+ polsu=two*polsu/real(nlon,r_kind)
+ polsv=two*polsv/real(nlon,r_kind)
do ix=1,nlon
grid4n(ix)=-polnu*sinlon(ix)+polnv*coslon(ix)
grid4s(ix)= polsu*sinlon(ix)-polsv*coslon(ix)
@@ -2330,10 +2314,10 @@ subroutine tcompact_dlat(b,dbdy,vector)
polsu=polsu+sinlon(ix)*grid4s(ix)
polsv=polsv-coslon(ix)*grid4s(ix)
end do
- polnu=two*polnu/float(nlon)
- polnv=two*polnv/float(nlon)
- polsu=two*polsu/float(nlon)
- polsv=two*polsv/float(nlon)
+ polnu=two*polnu/real(nlon,r_kind)
+ polnv=two*polnv/real(nlon,r_kind)
+ polsu=two*polsu/real(nlon,r_kind)
+ polsv=two*polsv/real(nlon,r_kind)
do ix=1,nlon
grid4(ny,ix)=grid4(ny,ix)-sinlon(ix)*polnu+coslon(ix)*polnv
grid4(1 ,ix)=grid4(1 ,ix)+sinlon(ix)*polsu-coslon(ix)*polsv
diff --git a/src/gsi/compute_derived.f90 b/src/gsi/compute_derived.f90
index 46413d9986..32df50445f 100644
--- a/src/gsi/compute_derived.f90
+++ b/src/gsi/compute_derived.f90
@@ -467,7 +467,7 @@ subroutine compute_derived(mype,init_pass)
do i=indices%ips,indices%ipe
l =max(min(int(rllatf(i,j)),mlat),1)
l2=min((l+1),mlat)
- dl2=rllatf(i,j)-float(l)
+ dl2=rllatf(i,j)-real(l,r_kind)
dl1=one-dl2
factk=dl1*corz(l,kvar,nrf3_q)+dl2*corz(l2,kvar,nrf3_q)
diff --git a/src/gsi/compute_qvar3d.f90 b/src/gsi/compute_qvar3d.f90
index 851212d4f5..8babcc82fe 100644
--- a/src/gsi/compute_qvar3d.f90
+++ b/src/gsi/compute_qvar3d.f90
@@ -141,7 +141,7 @@ subroutine compute_qvar3d
d=20.0_r_kind*rhgues(i,j,k) + one
n=int(d)
np=n+1
- dn2=d-float(n)
+ dn2=d-real(n,r_kind)
dn1=one-dn2
n=min0(max(1,n),maxvarq1)
np=min0(max(1,np),maxvarq1)
@@ -200,7 +200,7 @@ subroutine compute_qvar3d
d=-2.0_r_kind*log(cwtmp) + one
n=int(d)
np=n+1
- dn2=d-float(n)
+ dn2=d-real(n,r_kind)
dn1=one-dn2
n=min0(max(1,n),30)
np=min0(max(1,np),30)
diff --git a/src/gsi/constants.f90 b/src/gsi/constants.f90
index 484e46b8b8..bf2b273c5f 100644
--- a/src/gsi/constants.f90
+++ b/src/gsi/constants.f90
@@ -74,9 +74,10 @@ module constants
public :: psv_a, psv_b, psv_c, psv_d
public :: ef_alpha, ef_beta, ef_gamma
public :: max_varname_length
+ public :: max_filename_length
public :: z_w_max,tfrozen
public :: qmin,qcmin,tgmin
- public :: i_missing, r_missing
+ public :: i_missing, r_missing, s_missing
public :: tice,t_wfr,e00,rvgas,rdgas,hlv,hlf,cp_vap,c_liq,c_ice,cp_air,cv_air
public :: izero, qimin, qsmin, qgmin,qrmin
@@ -90,7 +91,8 @@ module constants
! Declare derived constants
integer(i_kind):: huge_i_kind
- integer(i_kind), parameter :: max_varname_length=64
+ integer(i_kind), parameter :: max_varname_length=20
+ integer(i_kind), parameter :: max_filename_length=80
real(r_single):: tiny_single, huge_single
real(r_kind):: xai, xa, xbi, xb, dldt, rozcon,ozcon,fv, tpwcon,eps, rd_over_g
real(r_kind):: el2orc, g_over_rd, rd_over_cp, cpr, omeps, epsm1, factor2
@@ -287,6 +289,7 @@ module constants
! Constant used to detect missing input value
integer(i_kind),parameter:: i_missing=-9999
integer(r_kind),parameter:: r_missing=-9999._r_kind
+ real(r_single),parameter:: s_missing = -9.99e9_r_single
! Constants initialized
logical :: constants_initialized = .true.
diff --git a/src/gsi/control2state.f90 b/src/gsi/control2state.f90
index fb87c1d0ef..9dd4bca7b3 100644
--- a/src/gsi/control2state.f90
+++ b/src/gsi/control2state.f90
@@ -1,3 +1,58 @@
+!-------------------------------------------------------------------------
+! NOAA/NCEP, National Centers for Environmental Prediction GSI !
+!-------------------------------------------------------------------------
+!BOP
+!
+! !MODULE: control2state_mod --- control2state_mod variables and routines
+!
+! !INTERFACE:
+!
+module control2state_mod
+
+! !USES:
+
+
+! !DESCRIPTION: module control2state routines and variables
+
+use kinds, only: r_kind,i_kind
+use constants, only : max_varname_length, zero
+use control_vectors, only: control_vector,c2sset_flg
+use control_vectors, only: cvars3d,cvars2d
+use bias_predictors, only: predictors
+use jfunc, only: nsclen,npclen,ntclen
+use gsi_4dvar, only: nsubwin, l4dvar, lsqrtb,ladtest_obs
+use gsi_chemguess_mod, only: gsi_chemguess_get
+use gsi_metguess_mod, only: gsi_metguess_get
+use gsi_bundlemod, only: gsi_bundlegetpointer
+use gsi_bundlemod, only: gsi_bundlecreate
+use gsi_bundlemod, only: gsi_bundle
+use gsi_bundlemod, only: gsi_bundlegetvar
+use gsi_bundlemod, only: gsi_bundleputvar
+use gsi_bundlemod, only: gsi_bundledestroy
+use gsi_bundlemod, only: assignment(=)
+use gridmod, only: nems_nmmb_regional
+use gridmod, only: regional, twodvar_regional
+use gridmod, only: lat2,lon2,nsig,nlat,nlon
+use chemmod, only: laeroana_fv3cmaq, naero_cmaq_fv3,aeronames_cmaq_fv3,imodes_cmaq_fv3,icvt_cmaq_fv3
+use mpeu_util, only: getindex
+
+implicit none
+
+private
+public :: control2state
+public :: control2state_ad
+
+logical :: do_getprs,do_normal_rh_to_q,do_tv_to_tsen,do_getuv,do_cw_to_hydro
+logical :: do_cw_to_hydro_hwrf
+
+integer(i_kind) :: icpblh,icgust,icvis,icoz,icwspd10m,icw
+integer(i_kind) :: ictd2m,icmxtm,icmitm,icpmsl,ichowv
+integer(i_kind) :: icsfwter,icvpwter,ictcamt,iclcbas
+integer(i_kind) :: iccldch,icuwnd10m,icvwnd10m
+
+integer :: ngases,nclouds
+
+contains
subroutine control2state(xhat,sval,bval)
!$$$ subprogram documentation block
! . . . .
@@ -57,31 +112,11 @@ subroutine control2state(xhat,sval,bval)
! bval - Bias predictors
!
!$$$ end documentation block
-use kinds, only: r_kind,i_kind
-use control_vectors, only: control_vector
-use control_vectors, only: cvars3d,cvars2d
-use bias_predictors, only: predictors
-use gsi_4dvar, only: nsubwin, l4dvar, lsqrtb, ladtest_obs
-use gridmod, only: regional,lat2,lon2,nsig, nlat, nlon, twodvar_regional
-use jfunc, only: nsclen,npclen,ntclen
-use cwhydromod, only: cw2hydro_tl
use amassaeromod, only: amass2aero_tl
-use cwhydromod, only: cw2hydro_tl_hwrf
-use gsi_bundlemod, only: gsi_bundlecreate
-use gsi_bundlemod, only: gsi_bundle
-use gsi_bundlemod, only: gsi_bundlegetpointer
-use gsi_bundlemod, only: gsi_bundlegetvar
-use gsi_bundlemod, only: gsi_bundleputvar
-use gsi_bundlemod, only: gsi_bundledestroy
-use gsi_bundlemod, only: assignment(=)
-use gsi_chemguess_mod, only: gsi_chemguess_get
-use gsi_metguess_mod, only: gsi_metguess_get
-use mpeu_util, only: getindex
-use constants, only : max_varname_length, zero
use general_sub2grid_mod, only: general_sub2grid,general_grid2sub
use general_commvars_mod, only: s2g_cv
-use gridmod, only: nems_nmmb_regional
-use chemmod, only: laeroana_fv3cmaq, naero_cmaq_fv3,aeronames_cmaq_fv3,imodes_cmaq_fv3,icvt_cmaq_fv3
+use cwhydromod, only: cw2hydro_tl
+use cwhydromod, only: cw2hydro_tl_hwrf
implicit none
! Declare passed variables
@@ -94,22 +129,9 @@ subroutine control2state(xhat,sval,bval)
character(len=max_varname_length),allocatable,dimension(:) :: gases
character(len=max_varname_length),allocatable,dimension(:) :: clouds
real(r_kind),dimension(nlat*nlon*s2g_cv%nlevs_alloc) :: hwork
-integer(i_kind) :: ii,jj,ic,id,ngases,nclouds,istatus,istatus_oz
+integer(i_kind) :: ii,jj,ic,id,istatus,istatus_oz
type(gsi_bundle):: wbundle ! work bundle
-! Note: The following does not aim to get all variables in
-! the state and control vectors, but rather the ones
-! this routines knows how to handle.
-! Declare required local control variables
-integer(i_kind), parameter :: ncvars = 9
-integer(i_kind) :: icps(ncvars)
-integer(i_kind) :: icpblh,icgust,icvis,icoz,icwspd10m,icw
-integer(i_kind) :: ictd2m,icmxtm,icmitm,icpmsl,ichowv
-integer(i_kind) :: icsfwter,icvpwter,ictcamt,iclcbas
-integer(i_kind) :: iccldch,icuwnd10m,icvwnd10m
-character(len=3), parameter :: mycvars(ncvars) = (/ & ! vars from CV needed here
- 'sf ', 'vp ', 'ps ', 't ', 'q ', 'cw ', 'ql ', 'qi ', 'w ' /)
-logical :: lc_sf,lc_vp,lc_w,lc_ps,lc_t,lc_rh,lc_cw,lc_ql,lc_qi
real(r_kind),pointer,dimension(:,:) :: cv_ps=>NULL()
real(r_kind),pointer,dimension(:,:) :: cv_lcbas=>NULL()
real(r_kind),pointer,dimension(:,:,:) :: cv_sf=>NULL()
@@ -120,14 +142,6 @@ subroutine control2state(xhat,sval,bval)
real(r_kind),pointer,dimension(:,:,:) :: cv_sfwter=>NULL()
real(r_kind),pointer,dimension(:,:,:) :: cv_vpwter=>NULL()
-! Declare required local state variables
-integer(i_kind), parameter :: nsvars = 12
-integer(i_kind) :: isps(nsvars)
-character(len=4), parameter :: mysvars(nsvars) = (/ & ! vars from ST needed here
- 'u ', 'v ', 'prse', 'q ', 'tsen', 'ql ', 'qi ', 'w ', &
- 'qr ', 'qs ', 'qg ', 'qh ' /)
-logical :: ls_u,ls_v,ls_w,ls_prse,ls_q,ls_tsen,ls_ql,ls_qi
-logical :: ls_qr,ls_qs,ls_qg,ls_qh
real(r_kind),pointer,dimension(:,:) :: sv_ps=>NULL(),sv_sst=>NULL()
real(r_kind),pointer,dimension(:,:) :: sv_gust=>NULL(),sv_vis=>NULL(),sv_pblh=>NULL()
real(r_kind),pointer,dimension(:,:) :: sv_wspd10m=>NULL(),sv_tcamt=>NULL(),sv_lcbas=>NULL()
@@ -143,82 +157,17 @@ subroutine control2state(xhat,sval,bval)
real(r_kind),allocatable,dimension(:,:,:):: uland,vland,uwter,vwter
-logical :: do_getprs_tl,do_normal_rh_to_q,do_tv_to_tsen,do_getuv,do_cw_to_hydro
-logical :: do_cw_to_hydro_hwrf
-
-
-if (lsqrtb) then
- write(6,*)trim(myname),': not for sqrt(B)'
- call stop2(106)
-end if
-if (nsubwin/=1 .and. .not.l4dvar) then
- write(6,*)trim(myname),': error 3dvar',nsubwin,l4dvar
- call stop2(107)
-end if
-
-! Inquire about cloud-vars
-call gsi_metguess_get('clouds::3d',nclouds,istatus)
+if (c2sset_flg)call c2sset(xhat,sval)
if (nclouds>0) then
allocate(clouds(nclouds))
call gsi_metguess_get('clouds::3d',clouds,istatus)
end if
-! Inquire about chemistry
-call gsi_chemguess_get('dim',ngases,istatus)
if (ngases>0) then
allocate(gases(ngases))
call gsi_chemguess_get('gsinames',gases,istatus)
endif
-! Since each internal vector of xhat has the same structure, pointers are
-! the same independent of the subwindow jj
-call gsi_bundlegetpointer (xhat%step(1),mycvars,icps,istatus)
-lc_sf =icps(1)>0; lc_vp =icps(2)>0; lc_ps =icps(3)>0
-lc_t =icps(4)>0; lc_rh =icps(5)>0; lc_cw =icps(6)>0
-lc_ql =icps(7)>0; lc_qi =icps(8)>0; lc_w =icps(9)>0
-
-! Since each internal vector of xhat has the same structure, pointers are
-! the same independent of the subwindow jj
-call gsi_bundlegetpointer (sval(1),mysvars,isps,istatus)
-ls_u =isps(1)>0; ls_v =isps(2)>0; ls_prse=isps(3)>0
-ls_q =isps(4)>0; ls_tsen=isps(5)>0; ls_ql =isps(6)>0
-ls_qi =isps(7)>0; ls_w =isps(8)>0
-ls_qr =isps(9)>0; ls_qs =isps(10)>0
-ls_qg =isps(11)>0; ls_qh =isps(12)>0
-
-! Define what to do depending on what's in CV and SV
-do_getprs_tl =lc_ps.and.lc_t .and.ls_prse
-do_normal_rh_to_q=lc_rh.and.lc_t .and.ls_prse.and.ls_q
-do_tv_to_tsen =lc_t .and.ls_q .and.ls_tsen
-do_getuv =lc_sf.and.lc_vp.and.ls_u.and.ls_v
-
-do_cw_to_hydro=.false.
-do_cw_to_hydro_hwrf=.false.
-if (regional) then
- do_cw_to_hydro=lc_cw.and.ls_ql.and.ls_qi
- do_cw_to_hydro_hwrf=lc_cw.and.ls_ql.and.ls_qi.and.ls_qr.and.ls_qs.and.ls_qg.and.ls_qh
-else
- do_cw_to_hydro=lc_cw.and.ls_tsen.and.ls_ql.and.ls_qi.and.(.not.lc_ql) !ncep global
-endif
-
-call gsi_bundlegetpointer (xhat%step(1),'oz',icoz,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'gust',icgust,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'vis',icvis,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'pblh',icpblh,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'wspd10m',icwspd10m,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'td2m',ictd2m,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'mxtm',icmxtm,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'mitm',icmitm,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'pmsl',icpmsl,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'howv',ichowv,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'sfwter',icsfwter,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'vpwter',icvpwter,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'w',icw,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'tcamt',ictcamt,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'lcbas',iclcbas,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'cldch',iccldch,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'uwnd10m',icuwnd10m,istatus)
-call gsi_bundlegetpointer (xhat%step(1),'vwnd10m',icvwnd10m,istatus)
! Loop over control steps
do jj=1,nsubwin
@@ -265,23 +214,6 @@ subroutine control2state(xhat,sval,bval)
end if
end if
- if(jj == 1)then
-! Biases
- do ii=1,nsclen
- bval%predr(ii)=xhat%predr(ii)
- enddo
-
- do ii=1,npclen
- bval%predp(ii)=xhat%predp(ii)
- enddo
-
- if (ntclen>0) then
- do ii=1,ntclen
- bval%predt(ii)=xhat%predt(ii)
- enddo
- end if
- end if
-
!$omp section
! Get pointers to required state variables
call gsi_bundlegetpointer (sval(jj),'prse',sv_prse,istatus)
@@ -295,7 +227,7 @@ subroutine control2state(xhat,sval,bval)
! Copy other variables
call gsi_bundlegetvar ( wbundle, 't' , sv_tv, istatus )
! Get 3d pressure
- if(do_getprs_tl) call getprs_tl(cv_ps,cv_t,sv_prse)
+ if(do_getprs) call getprs_tl(cv_ps,cv_t,sv_prse)
! Convert input normalized RH to q
if(do_normal_rh_to_q) call normal_rh_to_q(cv_rh,cv_t,sv_prse,sv_q)
@@ -330,14 +262,57 @@ subroutine control2state(xhat,sval,bval)
call gsi_bundlegetvar ( wbundle, 'ps' , sv_ps, istatus )
!$omp section
- call gsi_bundlegetpointer (sval(jj),'sst' ,sv_sst, istatus)
- call gsi_bundlegetvar ( wbundle, 'sst', sv_sst, istatus )
call gsi_bundlegetpointer (sval(jj),'oz' ,sv_oz , istatus_oz)
if (icoz>0) then
call gsi_bundlegetvar ( wbundle, 'oz' , sv_oz, istatus )
else
if(istatus_oz==0) sv_oz=zero
end if
+
+! Same one-to-one map for chemistry-vars; take care of them together
+ if (.not.laeroana_fv3cmaq .and. icvt_cmaq_fv3 == 2) then
+ write(6,*) ' icvt_cmaq_fv3 == 2 but laeroana_fv3cmaq=false stop!!!'
+ call stop2(999)
+ endif
+ if (icvt_cmaq_fv3 == 2) then
+ call amass2aero_tl(sval(jj),wbundle,aeronames_cmaq_fv3,naero_cmaq_fv3)
+ else
+ do ic=1,ngases
+ ! take care gases and aero variables if one to one mapping
+ id=getindex(cvars3d,gases(ic))
+ if (id>0) then
+ call gsi_bundlegetpointer (sval(jj),gases(ic),sv_rank3,istatus)
+ call gsi_bundlegetvar (wbundle, gases(ic),sv_rank3,istatus)
+ endif
+ id=getindex(cvars2d,gases(ic))
+ if (id>0) then
+ call gsi_bundlegetpointer (sval(jj),gases(ic),sv_rank2,istatus)
+ call gsi_bundlegetvar (wbundle, gases(ic),sv_rank2,istatus)
+ endif
+ enddo
+ end if
+
+!$omp section
+ if(jj == 1)then
+! Biases
+ do ii=1,nsclen
+ bval%predr(ii)=xhat%predr(ii)
+ enddo
+
+ do ii=1,npclen
+ bval%predp(ii)=xhat%predp(ii)
+ enddo
+
+ if (ntclen>0) then
+ do ii=1,ntclen
+ bval%predt(ii)=xhat%predt(ii)
+ enddo
+ end if
+ end if
+
+ call gsi_bundlegetpointer (sval(jj),'sst' ,sv_sst, istatus)
+ call gsi_bundlegetvar ( wbundle, 'sst', sv_sst, istatus )
+
if (icgust>0) then
call gsi_bundlegetpointer (sval(jj),'gust' ,sv_gust, istatus)
call gsi_bundlegetvar ( wbundle, 'gust', sv_gust, istatus )
@@ -405,43 +380,491 @@ subroutine control2state(xhat,sval,bval)
call gsi_bundlegetvar ( wbundle, 'vwnd10m', sv_vwnd10m, istatus )
end if
-! Same one-to-one map for chemistry-vars; take care of them together
+
+!$omp end parallel sections
+
+! Clean up
+ call gsi_bundledestroy(wbundle,istatus)
+ if(istatus/=0) then
+ write(6,*) trim(myname), ': trouble destroying work bundle'
+ call stop2(999)
+ endif
+
+end do
+
+if (ngases>0) deallocate(gases)
+
+if (nclouds>0) deallocate(clouds)
+
+return
+end subroutine control2state
+subroutine c2sset(xhat,sval)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: c2sset
+! prgmmr: derber
+!
+! abstract: Sets flags for control2state and control2state_ad
+!
+! program history log:
+! 2022-08-30 derber - initial code from control2state
+
+! input argument list:
+! xhat - Control variable
+! sval - State variable
+!
+!$$$ end documentation block
+implicit none
+
+! Declare passed variables
+type(control_vector), intent(in) :: xhat
+type(gsi_bundle) , intent(in) :: sval(nsubwin)
+
+! Declare local variables
+character(len=*),parameter::myname='c2sset'
+integer(i_kind) :: istatus
+
+! Note: The following does not aim to get all variables in
+! the state and control vectors, but rather the ones
+! this routines knows how to handle.
+! Declare required local control variables
+integer(i_kind), parameter :: ncvars = 9
+integer(i_kind) :: icps(ncvars)
+character(len=3), parameter :: mycvars(ncvars) = (/ & ! vars from CV needed here
+ 'sf ', 'vp ', 'ps ', 't ', 'q ', 'cw ', 'ql ', 'qi ', 'w ' /)
+logical :: lc_sf,lc_vp,lc_w,lc_ps,lc_t,lc_rh,lc_cw,lc_ql,lc_qi
+
+! Declare required local state variables
+integer(i_kind), parameter :: nsvars = 12
+integer(i_kind) :: isps(nsvars)
+character(len=4), parameter :: mysvars(nsvars) = (/ & ! vars from ST needed here
+ 'u ', 'v ', 'prse', 'q ', 'tsen', 'ql ', 'qi ', 'w ', &
+ 'qr ', 'qs ', 'qg ', 'qh ' /)
+logical :: ls_u,ls_v,ls_w,ls_prse,ls_q,ls_tsen,ls_ql,ls_qi
+logical :: ls_qr,ls_qs,ls_qg,ls_qh
+
+
+
+if (lsqrtb) then
+ write(6,*)trim(myname),': not for sqrt(B)'
+ call stop2(106)
+end if
+if (nsubwin/=1 .and. .not.l4dvar) then
+ write(6,*)trim(myname),': error 3dvar',nsubwin,l4dvar
+ call stop2(107)
+end if
+
+! Inquire about cloud-vars
+call gsi_metguess_get('clouds::3d',nclouds,istatus)
+
+! Inquire about chemistry
+call gsi_chemguess_get('dim',ngases,istatus)
+
+! Since each internal vector of xhat has the same structure, pointers are
+! the same independent of the subwindow jj
+call gsi_bundlegetpointer (xhat%step(1),mycvars,icps,istatus)
+lc_sf =icps(1)>0; lc_vp =icps(2)>0; lc_ps =icps(3)>0
+lc_t =icps(4)>0; lc_rh =icps(5)>0; lc_cw =icps(6)>0
+lc_ql =icps(7)>0; lc_qi =icps(8)>0; lc_w =icps(9)>0
+
+! Since each internal vector of sval has the same structure, pointers are
+! the same independent of the subwindow jj
+call gsi_bundlegetpointer (sval(1),mysvars,isps,istatus)
+ls_u =isps(1)>0; ls_v =isps(2)>0; ls_prse=isps(3)>0
+ls_q =isps(4)>0; ls_tsen=isps(5)>0; ls_ql =isps(6)>0
+ls_qi =isps(7)>0; ls_w =isps(8)>0
+ls_qr =isps(9)>0; ls_qs =isps(10)>0
+ls_qg =isps(11)>0; ls_qh =isps(12)>0
+
+! Define what to do depending on what's in CV and SV
+do_getprs =lc_ps.and.lc_t .and.ls_prse
+do_normal_rh_to_q=lc_rh.and.lc_t .and.ls_prse.and.ls_q
+do_tv_to_tsen =lc_t .and.ls_q .and.ls_tsen
+do_getuv =lc_sf.and.lc_vp.and.ls_u.and.ls_v
+
+do_cw_to_hydro=.false.
+do_cw_to_hydro_hwrf=.false.
+if (regional) then
+ do_cw_to_hydro=lc_cw.and.ls_ql.and.ls_qi
+ do_cw_to_hydro_hwrf=lc_cw.and.ls_ql.and.ls_qi.and.ls_qr.and.ls_qs.and.ls_qg.and.ls_qh
+else
+ do_cw_to_hydro=lc_cw.and.ls_tsen.and.ls_ql.and.ls_qi.and.(.not.lc_ql) !ncep global
+endif
+
+call gsi_bundlegetpointer (xhat%step(1),'oz',icoz,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'gust',icgust,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'vis',icvis,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'pblh',icpblh,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'wspd10m',icwspd10m,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'td2m',ictd2m,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'mxtm',icmxtm,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'mitm',icmitm,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'pmsl',icpmsl,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'howv',ichowv,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'sfwter',icsfwter,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'vpwter',icvpwter,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'w',icw,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'tcamt',ictcamt,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'lcbas',iclcbas,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'cldch',iccldch,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'uwnd10m',icuwnd10m,istatus)
+call gsi_bundlegetpointer (xhat%step(1),'vwnd10m',icvwnd10m,istatus)
+
+c2sset_flg=.false. ! set to true in setup. set to false after first (only) call to c2sset
+return
+end subroutine c2sset
+subroutine control2state_ad(rval,bval,grad)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: control2state_ad
+! prgmmr: tremolet
+!
+! abstract: Converts variables from physical space to control space
+! This is also the adjoint of control2state
+!
+! program history log:
+! 2007-04-16 tremolet - initial code
+! 2008-11-28 todling - update to GSI May 2008: add tsen and p3d
+! 2009-01-15 todling - handle predictors in quad precision
+! 2009-04-21 derber - modify call to getstvp to call to getuv
+! 2009-06-15 parrish - add call to strong_bk_ad when l_hyb_ens=.true. (hybrid ensemble run)
+! 2009-08-12 lueken - update documentation
+! 2009-11-27 parrish - for uv_hyb_ens=.true., then ensemble perturbations contain u,v instead of st,vp
+! so introduce extra code to handle this case.
+! 2010-02-20 parrish - introduce modifications to allow dual resolution capability when running
+! in hybrid ensemble mode.
+! 2010-03-24 zhu - use cstate for generalizing control variable
+! 2010-04-29 todling - update to use gsi_bundle; rename cstate to wbundle
+! 2010-05-31 todling - better consistency checks; add co/co2
+! - ready to bypass analysis of (any) meteorological fields
+! 2010-06-15 todling - generalized handling of chemistry
+! 2011-02-22 zhu - add gust,vis,pblh
+! 2011-05-15 auligne/todling - generalized cloud handling
+! 2011-07-12 zhu - add do_cw_to_hydro_ad and cw2hydro_ad
+! 2011-11-01 eliu - generalize the use of do_cw_to_hydro_ad
+! 2012-02-08 kleist - remove strong_bk_ad and ensemble_forward_model_ad and related parameters
+! 2013-05-23 zhu - add ntclen and predt for aircraft temperature bias correction
+! 2013-10-25 todling - nullify work pointers
+! 2013-10-28 todling - rename p3d to prse
+! 2014-01-31 mkim - add support for when ql and qi are CVs for all-sky mw radiance DA
+! 2014-03-19 pondeca - add wspd10m
+! 2014-04-10 pondeca - add td2m,mxtm,mitm,pmsl
+! 2014-05-07 pondeca - add howv
+! 2014-06-16 carley/zhu - add tcamt and lcbas
+! 2014-12-03 derber - introduce parallel regions for optimization
+! 2015-07-10 pondeca - add cloud ceiling height (cldch)
+! 2016-05-03 pondeca - add uwnd10m, and vwnd10m
+! 2017-05-12 Y. Wang and X. Wang - add w as state variable for rw DA, POC: xuguang.wang@ou.edu
+! 2016-08-12 lippi - add vertical velocity (w) to mycvars and mysvars.
+! 2016-05-03 pondeca - add uwnd10m, and vwnd10m
+! 2022-05-24 H.Wang - add amass2aero_ad for regional FV3-CMAQ DA when using
+! total mass as control variable.
+!
+! input argument list:
+! rval - State variable
+! bval
+! output argument list:
+! grad - Control variable
+!
+!$$$
+use amassaeromod, only: amass2aero_ad
+use cwhydromod, only: cw2hydro_ad
+use cwhydromod, only: cw2hydro_ad_hwrf
+
+implicit none
+
+! Declare passed variables
+type(gsi_bundle) , intent(inout) :: rval(nsubwin)
+type(predictors) , intent(in ) :: bval
+type(control_vector), intent(inout) :: grad
+
+! Declare local variables
+character(len=*),parameter::myname='control2state_ad'
+character(len=max_varname_length),allocatable,dimension(:) :: gases
+character(len=max_varname_length),allocatable,dimension(:) :: clouds
+integer(i_kind) :: ii,jj,ic,id,istatus,istatus_oz
+type(gsi_bundle) :: wbundle ! work bundle
+
+real(r_kind),pointer,dimension(:,:) :: cv_ps=>NULL()
+real(r_kind),pointer,dimension(:,:) :: cv_lcbas=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: cv_sf=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: cv_vp=>NULL()
+!real(r_kind),pointer,dimension(:,:,:) :: cv_w=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: cv_t=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: cv_rh=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: cv_sfwter=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: cv_vpwter=>NULL()
+
+! Declare required local state variables
+real(r_kind),pointer,dimension(:,:) :: rv_ps=>NULL(),rv_sst=>NULL()
+real(r_kind),pointer,dimension(:,:) :: rv_gust=>NULL(),rv_vis=>NULL(),rv_pblh=>NULL()
+real(r_kind),pointer,dimension(:,:) :: rv_wspd10m=>NULL(),rv_tcamt=>NULL(),rv_lcbas=>NULL()
+real(r_kind),pointer,dimension(:,:) :: rv_td2m=>NULL(),rv_mxtm=>NULL(),rv_mitm=>NULL()
+real(r_kind),pointer,dimension(:,:) :: rv_pmsl=>NULL(),rv_howv=>NULL(),rv_cldch=>NULL()
+real(r_kind),pointer,dimension(:,:) :: rv_uwnd10m=>NULL(),rv_vwnd10m=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_u=>NULL(),rv_v=>NULL(),rv_w=>NULL(),rv_dw=>NULL(),rv_prse=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_q=>NULL(),rv_tsen=>NULL(),rv_tv=>NULL(),rv_oz=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_rank3=>NULL()
+real(r_kind),pointer,dimension(:,:) :: rv_rank2=>NULL()
+
+real(r_kind),allocatable,dimension(:,:,:):: uland,vland,uwter,vwter
+
+
+
+!******************************************************************************
+
+if (c2sset_flg)call c2sset(grad,rval)
+if (lsqrtb) then
+ write(6,*)trim(myname),': not for sqrt(B)'
+ call stop2(311)
+end if
+
+! Inquire about clouds
+if (nclouds>0) then
+ allocate(clouds(nclouds))
+ call gsi_metguess_get ('clouds::3d',clouds,istatus)
+endif
+
+! Inquire about chemistry
+call gsi_chemguess_get('dim',ngases,istatus)
+if (ngases>0) then
+ allocate(gases(ngases))
+ call gsi_chemguess_get('gsinames',gases,istatus)
+endif
+
+
+! Loop over control steps
+do jj=1,nsubwin
+
+! Create a work bundle similar to grad control vector's bundle
+ call gsi_bundlecreate ( wbundle, grad%step(jj), 'control2state_ad work', istatus )
+ if (istatus/=0) then
+ write(6,*) trim(myname),': trouble creating work bundle'
+ call stop2(999)
+ endif
+
+!$omp parallel sections private(istatus,ii,ic,id,istatus_oz,rv_u,rv_v,rv_prse,rv_q,rv_tsen,uland,vland,uwter,vwter)
+
+!$omp section
+
+ call gsi_bundlegetpointer (wbundle,'sf' ,cv_sf ,istatus)
+ call gsi_bundlegetpointer (wbundle,'vp' ,cv_vp ,istatus)
+ call gsi_bundlegetpointer (rval(jj),'u' ,rv_u, istatus)
+ call gsi_bundlegetpointer (rval(jj),'v' ,rv_v, istatus)
+ call gsi_bundleputvar ( wbundle, 'sf', zero, istatus )
+ call gsi_bundleputvar ( wbundle, 'vp', zero, istatus )
+! Convert RHS calculations for u,v to st/vp for application of
+! background error
+ if (do_getuv) then
+ if (twodvar_regional .and. icsfwter>0 .and. icvpwter>0) then
+ call gsi_bundlegetpointer (wbundle,'sfwter', cv_sfwter,istatus)
+ call gsi_bundlegetpointer (wbundle,'vpwter', cv_vpwter,istatus)
+ allocate(uland(lat2,lon2,nsig),vland(lat2,lon2,nsig), &
+ uwter(lat2,lon2,nsig),vwter(lat2,lon2,nsig))
+
+ uland=zero ; uwter=zero
+ vland=zero ; vwter=zero
+
+ call landlake_uvmerge(rv_u,rv_v,uland,vland,uwter,vwter,0)
+
+ call getuv(uwter,vwter,cv_sfwter,cv_vpwter,1)
+ call getuv(uland,vland,cv_sf,cv_vp,1)
+ deallocate(uland,vland,uwter,vwter)
+ else
+ call getuv(rv_u,rv_v,cv_sf,cv_vp,1)
+ endif
+ endif
+
+!$omp section
+
+! Get pointers to required control variables
+ call gsi_bundlegetpointer (wbundle,'ps' ,cv_ps ,istatus)
+ call gsi_bundlegetpointer (wbundle,'t' ,cv_t, istatus)
+ call gsi_bundlegetpointer (wbundle,'q' ,cv_rh ,istatus)
+
+! Get pointers to this subwin require state variables
+ call gsi_bundlegetpointer (rval(jj),'ps' ,rv_ps, istatus)
+ call gsi_bundlegetpointer (rval(jj),'prse',rv_prse,istatus)
+ call gsi_bundlegetpointer (rval(jj),'tv' ,rv_tv, istatus)
+ call gsi_bundlegetpointer (rval(jj),'tsen',rv_tsen,istatus)
+ call gsi_bundlegetpointer (rval(jj),'q' ,rv_q , istatus)
+
+! Adjoint of control to initial state
+ call gsi_bundleputvar ( wbundle, 't' , rv_tv, istatus )
+ call gsi_bundleputvar ( wbundle, 'q' , zero, istatus )
+ call gsi_bundleputvar ( wbundle, 'ps', rv_ps, istatus )
+
+ if (do_cw_to_hydro .and. .not.do_cw_to_hydro_hwrf) then
+! Case when cloud-vars do not map one-to-one
+! e.g. cw-to-ql&qi
+ call cw2hydro_ad(rval(jj),wbundle,clouds,nclouds)
+ elseif (do_cw_to_hydro_hwrf) then
+! Case when cloud-vars do not map one-to-one
+! e.g. cw-to-ql&qi&qr&qs&qg&qh
+ call cw2hydro_ad_hwrf(rval(jj),wbundle,rv_tsen)
+ else
+! Case when cloud-vars map one-to-one, take care of them together
+! e.g. cw-to-cw
+ do ic=1,nclouds
+ id=getindex(cvars3d,clouds(ic))
+ if (id>0) then
+ call gsi_bundlegetpointer (rval(jj),clouds(ic),rv_rank3,istatus)
+ call gsi_bundleputvar (wbundle, clouds(ic),rv_rank3,istatus)
+ endif
+ enddo
+ end if
+! Calculate sensible temperature
+ if(do_tv_to_tsen) call tv_to_tsen_ad(cv_t,rv_q,rv_tsen)
+
+! Adjoint of convert input normalized RH to q to add contribution of moisture
+! to t, p , and normalized rh
+ if(do_normal_rh_to_q) call normal_rh_to_q_ad(cv_rh,cv_t,rv_prse,rv_q)
+
+! Adjoint to convert ps to 3-d pressure
+ if(do_getprs) call getprs_ad(cv_ps,cv_t,rv_prse)
+
+
+!$omp section
+
+
+! call gsi_bundlegetpointer (rval(jj),'oz' ,rv_oz , istatus)
+ call gsi_bundlegetpointer (rval(jj),'oz' ,rv_oz , istatus_oz)
+
+ if (icoz>0) then
+ call gsi_bundleputvar ( wbundle, 'oz', rv_oz, istatus )
+ else
+ if(istatus_oz==0) rv_oz=zero
+ end if
+
+! Same one-to-one map for chemistry-vars; take care of them together
if (.not.laeroana_fv3cmaq .and. icvt_cmaq_fv3 == 2) then
write(6,*) ' icvt_cmaq_fv3 == 2 but laeroana_fv3cmaq=false stop!!!'
call stop2(999)
endif
+
if (icvt_cmaq_fv3 == 2) then
- call amass2aero_tl(sval(jj),wbundle,aeronames_cmaq_fv3,naero_cmaq_fv3)
+ call amass2aero_ad(rval(jj),wbundle,aeronames_cmaq_fv3,naero_cmaq_fv3)
else
do ic=1,ngases
- ! take care gases and aero variables if one to one mapping
id=getindex(cvars3d,gases(ic))
if (id>0) then
- call gsi_bundlegetpointer (sval(jj),gases(ic),sv_rank3,istatus)
- call gsi_bundlegetvar (wbundle, gases(ic),sv_rank3,istatus)
+ call gsi_bundlegetpointer (rval(jj),gases(ic),rv_rank3,istatus)
+ call gsi_bundleputvar (wbundle, gases(ic),rv_rank3,istatus)
endif
+
id=getindex(cvars2d,gases(ic))
if (id>0) then
- call gsi_bundlegetpointer (sval(jj),gases(ic),sv_rank2,istatus)
- call gsi_bundlegetvar (wbundle, gases(ic),sv_rank2,istatus)
+ call gsi_bundlegetpointer (rval(jj),gases(ic),rv_rank2,istatus)
+ call gsi_bundleputvar (wbundle, gases(ic),rv_rank2,istatus)
endif
enddo
- end if
+ end if
+!$omp section
+ if(jj == 1)then
+ do ii=1,nsclen
+ grad%predr(ii)=bval%predr(ii)
+ enddo
+ do ii=1,npclen
+ grad%predp(ii)=bval%predp(ii)
+ enddo
+ if (ntclen>0) then
+ do ii=1,ntclen
+ grad%predt(ii)=bval%predt(ii)
+ enddo
+ end if
+ end if
+
+ call gsi_bundlegetpointer (rval(jj),'sst' ,rv_sst, istatus)
+ call gsi_bundleputvar ( wbundle, 'sst', rv_sst, istatus )
+
+ if (icgust>0) then
+ call gsi_bundlegetpointer (rval(jj),'gust' ,rv_gust, istatus)
+ call gsi_bundleputvar ( wbundle, 'gust', rv_gust, istatus )
+ end if
+ if (icvis >0) then
+ call gsi_bundlegetpointer (rval(jj),'vis' ,rv_vis , istatus)
+ call gsi_bundleputvar ( wbundle, 'vis' , rv_vis , istatus )
+ end if
+ if (icpblh>0)then
+ call gsi_bundlegetpointer (rval(jj),'pblh' ,rv_pblh, istatus)
+ call gsi_bundleputvar ( wbundle, 'pblh', rv_pblh, istatus )
+ end if
+ if (icwspd10m>0) then
+ call gsi_bundlegetpointer (rval(jj),'wspd10m' ,rv_wspd10m, istatus)
+ call gsi_bundleputvar ( wbundle, 'wspd10m', rv_wspd10m, istatus )
+ end if
+ if (ictd2m>0) then
+ call gsi_bundlegetpointer (rval(jj),'td2m' ,rv_td2m, istatus)
+ call gsi_bundleputvar ( wbundle, 'td2m', rv_td2m, istatus )
+ end if
+ if (icmxtm>0) then
+ call gsi_bundlegetpointer (rval(jj),'mxtm' ,rv_mxtm, istatus)
+ call gsi_bundleputvar ( wbundle, 'mxtm', rv_mxtm, istatus )
+ end if
+ if (icmitm>0) then
+ call gsi_bundlegetpointer (rval(jj),'mitm' ,rv_mitm, istatus)
+ call gsi_bundleputvar ( wbundle, 'mitm', rv_mitm, istatus )
+ end if
+ if (icpmsl>0) then
+ call gsi_bundlegetpointer (rval(jj),'pmsl' ,rv_pmsl, istatus)
+ call gsi_bundleputvar ( wbundle, 'pmsl', rv_pmsl, istatus )
+ end if
+ if (ichowv>0) then
+ call gsi_bundlegetpointer (rval(jj),'howv' ,rv_howv, istatus)
+ call gsi_bundleputvar ( wbundle, 'howv', rv_howv, istatus )
+ end if
+ if (icw>0) then
+ call gsi_bundlegetpointer (rval(jj),'w' ,rv_w, istatus)
+ call gsi_bundleputvar ( wbundle, 'w', rv_w, istatus )
+ if(nems_nmmb_regional)then
+ call gsi_bundlegetpointer (rval(jj),'dw' ,rv_dw, istatus)
+ call gsi_bundleputvar ( wbundle, 'dw', rv_dw, istatus )
+ end if
+ end if
+ if (ictcamt>0) then
+ call gsi_bundlegetpointer (rval(jj),'tcamt',rv_tcamt, istatus)
+ call gsi_bundleputvar ( wbundle, 'tcamt', rv_tcamt, istatus )
+ end if
+ if (iclcbas>0) then
+ call gsi_bundlegetpointer (wbundle,'lcbas',cv_lcbas,istatus)
+ call gsi_bundlegetpointer (rval(jj),'lcbas',rv_lcbas, istatus)
+ call gsi_bundleputvar ( wbundle, 'lcbas', zero, istatus )
+ ! Adjoint of convert loglcbas to lcbas
+ call loglcbas_to_lcbas_ad(cv_lcbas,rv_lcbas)
+ end if
+ if (iccldch >0) then
+ call gsi_bundlegetpointer (rval(jj),'cldch' ,rv_cldch , istatus)
+ call gsi_bundleputvar ( wbundle, 'cldch' , rv_cldch , istatus )
+ end if
+ if (icuwnd10m>0) then
+ call gsi_bundlegetpointer (rval(jj),'uwnd10m' ,rv_uwnd10m, istatus)
+ call gsi_bundleputvar ( wbundle, 'uwnd10m', rv_uwnd10m, istatus )
+ end if
+ if (icvwnd10m>0) then
+ call gsi_bundlegetpointer (rval(jj),'vwnd10m' ,rv_vwnd10m, istatus)
+ call gsi_bundleputvar ( wbundle, 'vwnd10m', rv_vwnd10m, istatus )
+ end if
!$omp end parallel sections
-! Clean up
+! Adjoint of transfer variables
+
+ do ii=1,wbundle%ndim
+ grad%step(jj)%values(ii)=wbundle%values(ii)+grad%step(jj)%values(ii)
+ enddo
call gsi_bundledestroy(wbundle,istatus)
- if(istatus/=0) then
- write(6,*) trim(myname), ': trouble destroying work bundle'
+ if (istatus/=0) then
+ write(6,*) trim(myname),': trouble destroying work bundle'
call stop2(999)
endif
end do
-if (ngases>0) deallocate(gases)
+! Clean up
+if (ngases>0) deallocate(gases)
if (nclouds>0) deallocate(clouds)
return
-end subroutine control2state
+end subroutine control2state_ad
+end module control2state_mod
diff --git a/src/gsi/control2state_ad.f90 b/src/gsi/control2state_ad.f90
deleted file mode 100644
index ce1e9d2cd2..0000000000
--- a/src/gsi/control2state_ad.f90
+++ /dev/null
@@ -1,441 +0,0 @@
-subroutine control2state_ad(rval,bval,grad)
-!$$$ subprogram documentation block
-! . . . .
-! subprogram: control2state_ad
-! prgmmr: tremolet
-!
-! abstract: Converts variables from physical space to control space
-! This is also the adjoint of control2state
-!
-! program history log:
-! 2007-04-16 tremolet - initial code
-! 2008-11-28 todling - update to GSI May 2008: add tsen and p3d
-! 2009-01-15 todling - handle predictors in quad precision
-! 2009-04-21 derber - modify call to getstvp to call to getuv
-! 2009-06-15 parrish - add call to strong_bk_ad when l_hyb_ens=.true. (hybrid ensemble run)
-! 2009-08-12 lueken - update documentation
-! 2009-11-27 parrish - for uv_hyb_ens=.true., then ensemble perturbations contain u,v instead of st,vp
-! so introduce extra code to handle this case.
-! 2010-02-20 parrish - introduce modifications to allow dual resolution capability when running
-! in hybrid ensemble mode.
-! 2010-03-24 zhu - use cstate for generalizing control variable
-! 2010-04-29 todling - update to use gsi_bundle; rename cstate to wbundle
-! 2010-05-31 todling - better consistency checks; add co/co2
-! - ready to bypass analysis of (any) meteorological fields
-! 2010-06-15 todling - generalized handling of chemistry
-! 2011-02-22 zhu - add gust,vis,pblh
-! 2011-05-15 auligne/todling - generalized cloud handling
-! 2011-07-12 zhu - add do_cw_to_hydro_ad and cw2hydro_ad
-! 2011-11-01 eliu - generalize the use of do_cw_to_hydro_ad
-! 2012-02-08 kleist - remove strong_bk_ad and ensemble_forward_model_ad and related parameters
-! 2013-05-23 zhu - add ntclen and predt for aircraft temperature bias correction
-! 2013-10-25 todling - nullify work pointers
-! 2013-10-28 todling - rename p3d to prse
-! 2014-01-31 mkim - add support for when ql and qi are CVs for all-sky mw radiance DA
-! 2014-03-19 pondeca - add wspd10m
-! 2014-04-10 pondeca - add td2m,mxtm,mitm,pmsl
-! 2014-05-07 pondeca - add howv
-! 2014-06-16 carley/zhu - add tcamt and lcbas
-! 2014-12-03 derber - introduce parallel regions for optimization
-! 2015-07-10 pondeca - add cloud ceiling height (cldch)
-! 2016-05-03 pondeca - add uwnd10m, and vwnd10m
-! 2017-05-12 Y. Wang and X. Wang - add w as state variable for rw DA, POC: xuguang.wang@ou.edu
-! 2016-08-12 lippi - add vertical velocity (w) to mycvars and mysvars.
-! 2016-05-03 pondeca - add uwnd10m, and vwnd10m
-! 2022-05-24 H.Wang - add amass2aero_ad for regional FV3-CMAQ DA when using
-! total mass as control variable.
-!
-! input argument list:
-! rval - State variable
-! bval
-! output argument list:
-! grad - Control variable
-!
-!$$$
-use kinds, only: i_kind,r_kind
-use control_vectors, only: control_vector
-use control_vectors, only: cvars3d,cvars2d
-use bias_predictors, only: predictors
-use gsi_4dvar, only: nsubwin, lsqrtb
-use gridmod, only: regional,lat2,lon2,nsig,twodvar_regional
-use jfunc, only: nsclen,npclen,ntclen
-use cwhydromod, only: cw2hydro_ad
-use amassaeromod, only: amass2aero_ad
-use cwhydromod, only: cw2hydro_ad_hwrf
-use gsi_bundlemod, only: gsi_bundlecreate
-use gsi_bundlemod, only: gsi_bundle
-use gsi_bundlemod, only: gsi_bundlegetpointer
-use gsi_bundlemod, only: gsi_bundlegetvar
-use gsi_bundlemod, only: gsi_bundleputvar
-use gsi_bundlemod, only: gsi_bundledestroy
-use gsi_chemguess_mod, only: gsi_chemguess_get
-use gsi_metguess_mod, only: gsi_metguess_get
-use mpeu_util, only: getindex
-use constants, only: max_varname_length,zero
-use gridmod, only: nems_nmmb_regional
-use chemmod, only: laeroana_fv3cmaq, naero_cmaq_fv3,aeronames_cmaq_fv3,imodes_cmaq_fv3,icvt_cmaq_fv3
-
-implicit none
-
-! Declare passed variables
-type(gsi_bundle) , intent(inout) :: rval(nsubwin)
-type(predictors) , intent(in ) :: bval
-type(control_vector), intent(inout) :: grad
-
-! Declare local variables
-character(len=*),parameter::myname='control2state_ad'
-character(len=max_varname_length),allocatable,dimension(:) :: gases
-character(len=max_varname_length),allocatable,dimension(:) :: clouds
-integer(i_kind) :: ii,jj,ic,id,ngases,nclouds,istatus,istatus_oz
-type(gsi_bundle) :: wbundle ! work bundle
-
-! Note: The following does not aim to get all variables in
-! the state and control vectors, but rather the ones
-! this routines knows how to handle.
-integer(i_kind), parameter :: ncvars = 9
-integer(i_kind) :: icps(ncvars)
-integer(i_kind) :: icpblh,icgust,icvis,icoz,icwspd10m,icw
-integer(i_kind) :: ictd2m,icmxtm,icmitm,icpmsl,ichowv
-integer(i_kind) :: ictcamt,iclcbas,icsfwter,icvpwter
-integer(i_kind) :: iccldch,icuwnd10m,icvwnd10m
-character(len=3), parameter :: mycvars(ncvars) = (/ &
- 'sf ', 'vp ', 'ps ', 't ', 'q ', 'cw ', 'ql ', 'qi ', 'w ' /)
-logical :: lc_sf,lc_vp,lc_w,lc_ps,lc_t,lc_rh,lc_cw,lc_ql,lc_qi
-real(r_kind),pointer,dimension(:,:) :: cv_ps=>NULL()
-real(r_kind),pointer,dimension(:,:) :: cv_lcbas=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: cv_sf=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: cv_vp=>NULL()
-!real(r_kind),pointer,dimension(:,:,:) :: cv_w=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: cv_t=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: cv_rh=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: cv_sfwter=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: cv_vpwter=>NULL()
-
-! Declare required local state variables
-integer(i_kind), parameter :: nsvars = 12
-integer(i_kind) :: isps(nsvars)
-character(len=4), parameter :: mysvars(nsvars) = (/ & ! vars from ST needed here
- 'u ', 'v ', 'prse', 'q ', 'tsen', 'ql ', 'qi ', 'w ', &
- 'qr ', 'qs ', 'qg ', 'qh ' /)
-logical :: ls_u,ls_v,ls_w,ls_prse,ls_q,ls_tsen,ls_ql,ls_qi
-logical :: ls_qr,ls_qs,ls_qg,ls_qh
-real(r_kind),pointer,dimension(:,:) :: rv_ps=>NULL(),rv_sst=>NULL()
-real(r_kind),pointer,dimension(:,:) :: rv_gust=>NULL(),rv_vis=>NULL(),rv_pblh=>NULL()
-real(r_kind),pointer,dimension(:,:) :: rv_wspd10m=>NULL(),rv_tcamt=>NULL(),rv_lcbas=>NULL()
-real(r_kind),pointer,dimension(:,:) :: rv_td2m=>NULL(),rv_mxtm=>NULL(),rv_mitm=>NULL()
-real(r_kind),pointer,dimension(:,:) :: rv_pmsl=>NULL(),rv_howv=>NULL(),rv_cldch=>NULL()
-real(r_kind),pointer,dimension(:,:) :: rv_uwnd10m=>NULL(),rv_vwnd10m=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_u=>NULL(),rv_v=>NULL(),rv_w=>NULL(),rv_dw=>NULL(),rv_prse=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_q=>NULL(),rv_tsen=>NULL(),rv_tv=>NULL(),rv_oz=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_rank3=>NULL()
-real(r_kind),pointer,dimension(:,:) :: rv_rank2=>NULL()
-
-real(r_kind),allocatable,dimension(:,:,:):: uland,vland,uwter,vwter
-
-logical :: do_getuv,do_tv_to_tsen_ad,do_normal_rh_to_q_ad,do_getprs_ad,do_cw_to_hydro_ad
-logical :: do_cw_to_hydro_ad_hwrf
-
-
-!******************************************************************************
-
-if (lsqrtb) then
- write(6,*)trim(myname),': not for sqrt(B)'
- call stop2(311)
-end if
-
-! Inquire about clouds
-call gsi_metguess_get ('clouds::3d',nclouds,istatus)
-if (nclouds>0) then
- allocate(clouds(nclouds))
- call gsi_metguess_get ('clouds::3d',clouds,istatus)
-endif
-
-! Inquire about chemistry
-call gsi_chemguess_get('dim',ngases,istatus)
-if (ngases>0) then
- allocate(gases(ngases))
- call gsi_chemguess_get('gsinames',gases,istatus)
-endif
-
-! Since each internal vector [step(jj)] of grad has the same structure, pointers are
-! the same independent of the subwindow jj
-call gsi_bundlegetpointer (grad%step(1),mycvars,icps,istatus)
-lc_sf =icps(1)>0; lc_vp =icps(2)>0; lc_ps =icps(3)>0
-lc_t =icps(4)>0; lc_rh =icps(5)>0; lc_cw =icps(6)>0
-lc_ql =icps(7)>0; lc_qi =icps(8)>0; lc_w =icps(9)>0
-
-! Since each internal vector of xhat has the same structure, pointers are
-! the same independent of the subwindow jj
-call gsi_bundlegetpointer (rval(1),mysvars,isps,istatus)
-ls_u =isps(1)>0; ls_v =isps(2)>0; ls_prse=isps(3)>0
-ls_q =isps(4)>0; ls_tsen=isps(5)>0; ls_ql =isps(6)>0
-ls_qi =isps(7)>0; ls_w =isps(8)>0
-ls_qr =isps(9)>0; ls_qs =isps(10)>0
-ls_qg =isps(11)>0; ls_qh =isps(12)>0
-
-! Define what to do depending on what's in CV and SV
-do_getuv =lc_sf.and.lc_vp.and.ls_u .and.ls_v
-do_tv_to_tsen_ad =lc_t .and.ls_q .and.ls_tsen
-do_normal_rh_to_q_ad=lc_t .and.lc_rh.and.ls_prse.and.ls_q
-do_getprs_ad =lc_t .and.lc_ps.and.ls_prse
-
-do_cw_to_hydro_ad=.false.
-do_cw_to_hydro_ad_hwrf=.false.
-if (regional) then
- do_cw_to_hydro_ad=lc_cw.and.ls_ql.and.ls_qi
- do_cw_to_hydro_ad_hwrf=lc_cw.and.ls_ql.and.ls_qi.and.ls_qr.and.ls_qs.and.ls_qg.and.ls_qh
-else
- do_cw_to_hydro_ad=lc_cw.and.ls_tsen.and.ls_ql.and.ls_qi.and.(.not.lc_ql) !ncep global
-endif
-
-call gsi_bundlegetpointer (grad%step(1),'oz',icoz,istatus)
-call gsi_bundlegetpointer (grad%step(1),'gust',icgust,istatus)
-call gsi_bundlegetpointer (grad%step(1),'vis',icvis,istatus)
-call gsi_bundlegetpointer (grad%step(1),'pblh',icpblh,istatus)
-call gsi_bundlegetpointer (grad%step(1),'wspd10m',icwspd10m,istatus)
-call gsi_bundlegetpointer (grad%step(1),'td2m',ictd2m,istatus)
-call gsi_bundlegetpointer (grad%step(1),'mxtm',icmxtm,istatus)
-call gsi_bundlegetpointer (grad%step(1),'mitm',icmitm,istatus)
-call gsi_bundlegetpointer (grad%step(1),'pmsl',icpmsl,istatus)
-call gsi_bundlegetpointer (grad%step(1),'howv',ichowv,istatus)
-call gsi_bundlegetpointer (grad%step(1),'sfwter',icsfwter,istatus)
-call gsi_bundlegetpointer (grad%step(1),'vpwter',icvpwter,istatus)
-call gsi_bundlegetpointer (grad%step(1),'w',icw,istatus)
-call gsi_bundlegetpointer (grad%step(1),'tcamt',ictcamt,istatus)
-call gsi_bundlegetpointer (grad%step(1),'lcbas',iclcbas,istatus)
-call gsi_bundlegetpointer (grad%step(1),'cldch',iccldch,istatus)
-call gsi_bundlegetpointer (grad%step(1),'uwnd10m',icuwnd10m,istatus)
-call gsi_bundlegetpointer (grad%step(1),'vwnd10m',icvwnd10m,istatus)
-
-! Loop over control steps
-do jj=1,nsubwin
-
-! Create a work bundle similar to grad control vector's bundle
- call gsi_bundlecreate ( wbundle, grad%step(jj), 'control2state_ad work', istatus )
- if (istatus/=0) then
- write(6,*) trim(myname),': trouble creating work bundle'
- call stop2(999)
- endif
-
-!$omp parallel sections private(istatus,ii,ic,id,istatus_oz,rv_u,rv_v,rv_prse,rv_q,rv_tsen,uland,vland,uwter,vwter)
-
-!$omp section
-
- call gsi_bundlegetpointer (wbundle,'sf' ,cv_sf ,istatus)
- call gsi_bundlegetpointer (wbundle,'vp' ,cv_vp ,istatus)
- call gsi_bundlegetpointer (rval(jj),'u' ,rv_u, istatus)
- call gsi_bundlegetpointer (rval(jj),'v' ,rv_v, istatus)
- call gsi_bundleputvar ( wbundle, 'sf', zero, istatus )
- call gsi_bundleputvar ( wbundle, 'vp', zero, istatus )
-! Convert RHS calculations for u,v to st/vp for application of
-! background error
- if (do_getuv) then
- if (twodvar_regional .and. icsfwter>0 .and. icvpwter>0) then
- call gsi_bundlegetpointer (wbundle,'sfwter', cv_sfwter,istatus)
- call gsi_bundlegetpointer (wbundle,'vpwter', cv_vpwter,istatus)
- allocate(uland(lat2,lon2,nsig),vland(lat2,lon2,nsig), &
- uwter(lat2,lon2,nsig),vwter(lat2,lon2,nsig))
-
- uland=zero ; uwter=zero
- vland=zero ; vwter=zero
-
- call landlake_uvmerge(rv_u,rv_v,uland,vland,uwter,vwter,0)
-
- call getuv(uwter,vwter,cv_sfwter,cv_vpwter,1)
- call getuv(uland,vland,cv_sf,cv_vp,1)
- deallocate(uland,vland,uwter,vwter)
- else
- call getuv(rv_u,rv_v,cv_sf,cv_vp,1)
- endif
- endif
-
- if(jj == 1)then
- do ii=1,nsclen
- grad%predr(ii)=bval%predr(ii)
- enddo
- do ii=1,npclen
- grad%predp(ii)=bval%predp(ii)
- enddo
- if (ntclen>0) then
- do ii=1,ntclen
- grad%predt(ii)=bval%predt(ii)
- enddo
- end if
- end if
-
-!$omp section
-
-! Get pointers to required control variables
- call gsi_bundlegetpointer (wbundle,'ps' ,cv_ps ,istatus)
- call gsi_bundlegetpointer (wbundle,'t' ,cv_t, istatus)
- call gsi_bundlegetpointer (wbundle,'q' ,cv_rh ,istatus)
-
-! Get pointers to this subwin require state variables
- call gsi_bundlegetpointer (rval(jj),'ps' ,rv_ps, istatus)
- call gsi_bundlegetpointer (rval(jj),'prse',rv_prse,istatus)
- call gsi_bundlegetpointer (rval(jj),'tv' ,rv_tv, istatus)
- call gsi_bundlegetpointer (rval(jj),'tsen',rv_tsen,istatus)
- call gsi_bundlegetpointer (rval(jj),'q' ,rv_q , istatus)
-
-! Adjoint of control to initial state
- call gsi_bundleputvar ( wbundle, 't' , rv_tv, istatus )
- call gsi_bundleputvar ( wbundle, 'q' , zero, istatus )
- call gsi_bundleputvar ( wbundle, 'ps', rv_ps, istatus )
-
- if (do_cw_to_hydro_ad .and. .not.do_cw_to_hydro_ad_hwrf) then
-! Case when cloud-vars do not map one-to-one
-! e.g. cw-to-ql&qi
- call cw2hydro_ad(rval(jj),wbundle,clouds,nclouds)
- elseif (do_cw_to_hydro_ad_hwrf) then
-! Case when cloud-vars do not map one-to-one
-! e.g. cw-to-ql&qi&qr&qs&qg&qh
- call cw2hydro_ad_hwrf(rval(jj),wbundle,rv_tsen)
- else
-! Case when cloud-vars map one-to-one, take care of them together
-! e.g. cw-to-cw
- do ic=1,nclouds
- id=getindex(cvars3d,clouds(ic))
- if (id>0) then
- call gsi_bundlegetpointer (rval(jj),clouds(ic),rv_rank3,istatus)
- call gsi_bundleputvar (wbundle, clouds(ic),rv_rank3,istatus)
- endif
- enddo
- end if
-! Calculate sensible temperature
- if(do_tv_to_tsen_ad) call tv_to_tsen_ad(cv_t,rv_q,rv_tsen)
-
-! Adjoint of convert input normalized RH to q to add contribution of moisture
-! to t, p , and normalized rh
- if(do_normal_rh_to_q_ad) call normal_rh_to_q_ad(cv_rh,cv_t,rv_prse,rv_q)
-
-! Adjoint to convert ps to 3-d pressure
- if(do_getprs_ad) call getprs_ad(cv_ps,cv_t,rv_prse)
-
-
-!$omp section
-
- call gsi_bundlegetpointer (rval(jj),'sst' ,rv_sst, istatus)
- call gsi_bundleputvar ( wbundle, 'sst', rv_sst, istatus )
-
-! call gsi_bundlegetpointer (rval(jj),'oz' ,rv_oz , istatus)
- call gsi_bundlegetpointer (rval(jj),'oz' ,rv_oz , istatus_oz)
-
- if (icoz>0) then
- call gsi_bundleputvar ( wbundle, 'oz', rv_oz, istatus )
- else
- if(istatus_oz==0) rv_oz=zero
- end if
-
-! Same one-to-one map for chemistry-vars; take care of them together
- if (.not.laeroana_fv3cmaq .and. icvt_cmaq_fv3 == 2) then
- write(6,*) ' icvt_cmaq_fv3 == 2 but laeroana_fv3cmaq=false stop!!!'
- call stop2(999)
- endif
-
- if (icvt_cmaq_fv3 == 2) then
- call amass2aero_ad(rval(jj),wbundle,aeronames_cmaq_fv3,naero_cmaq_fv3)
- else
- do ic=1,ngases
- id=getindex(cvars3d,gases(ic))
- if (id>0) then
- call gsi_bundlegetpointer (rval(jj),gases(ic),rv_rank3,istatus)
- call gsi_bundleputvar (wbundle, gases(ic),rv_rank3,istatus)
- endif
-
- id=getindex(cvars2d,gases(ic))
- if (id>0) then
- call gsi_bundlegetpointer (rval(jj),gases(ic),rv_rank2,istatus)
- call gsi_bundleputvar (wbundle, gases(ic),rv_rank2,istatus)
- endif
- enddo
- end if
- if (icgust>0) then
- call gsi_bundlegetpointer (rval(jj),'gust' ,rv_gust, istatus)
- call gsi_bundleputvar ( wbundle, 'gust', rv_gust, istatus )
- end if
- if (icvis >0) then
- call gsi_bundlegetpointer (rval(jj),'vis' ,rv_vis , istatus)
- call gsi_bundleputvar ( wbundle, 'vis' , rv_vis , istatus )
- end if
- if (icpblh>0)then
- call gsi_bundlegetpointer (rval(jj),'pblh' ,rv_pblh, istatus)
- call gsi_bundleputvar ( wbundle, 'pblh', rv_pblh, istatus )
- end if
- if (icwspd10m>0) then
- call gsi_bundlegetpointer (rval(jj),'wspd10m' ,rv_wspd10m, istatus)
- call gsi_bundleputvar ( wbundle, 'wspd10m', rv_wspd10m, istatus )
- end if
- if (ictd2m>0) then
- call gsi_bundlegetpointer (rval(jj),'td2m' ,rv_td2m, istatus)
- call gsi_bundleputvar ( wbundle, 'td2m', rv_td2m, istatus )
- end if
- if (icmxtm>0) then
- call gsi_bundlegetpointer (rval(jj),'mxtm' ,rv_mxtm, istatus)
- call gsi_bundleputvar ( wbundle, 'mxtm', rv_mxtm, istatus )
- end if
- if (icmitm>0) then
- call gsi_bundlegetpointer (rval(jj),'mitm' ,rv_mitm, istatus)
- call gsi_bundleputvar ( wbundle, 'mitm', rv_mitm, istatus )
- end if
- if (icpmsl>0) then
- call gsi_bundlegetpointer (rval(jj),'pmsl' ,rv_pmsl, istatus)
- call gsi_bundleputvar ( wbundle, 'pmsl', rv_pmsl, istatus )
- end if
- if (ichowv>0) then
- call gsi_bundlegetpointer (rval(jj),'howv' ,rv_howv, istatus)
- call gsi_bundleputvar ( wbundle, 'howv', rv_howv, istatus )
- end if
- if (icw>0) then
- call gsi_bundlegetpointer (rval(jj),'w' ,rv_w, istatus)
- call gsi_bundleputvar ( wbundle, 'w', rv_w, istatus )
- if(nems_nmmb_regional)then
- call gsi_bundlegetpointer (rval(jj),'dw' ,rv_dw, istatus)
- call gsi_bundleputvar ( wbundle, 'dw', rv_dw, istatus )
- end if
- end if
- if (ictcamt>0) then
- call gsi_bundlegetpointer (rval(jj),'tcamt',rv_tcamt, istatus)
- call gsi_bundleputvar ( wbundle, 'tcamt', rv_tcamt, istatus )
- end if
- if (iclcbas>0) then
- call gsi_bundlegetpointer (wbundle,'lcbas',cv_lcbas,istatus)
- call gsi_bundlegetpointer (rval(jj),'lcbas',rv_lcbas, istatus)
- call gsi_bundleputvar ( wbundle, 'lcbas', zero, istatus )
- ! Adjoint of convert loglcbas to lcbas
- call loglcbas_to_lcbas_ad(cv_lcbas,rv_lcbas)
- end if
- if (iccldch >0) then
- call gsi_bundlegetpointer (rval(jj),'cldch' ,rv_cldch , istatus)
- call gsi_bundleputvar ( wbundle, 'cldch' , rv_cldch , istatus )
- end if
- if (icuwnd10m>0) then
- call gsi_bundlegetpointer (rval(jj),'uwnd10m' ,rv_uwnd10m, istatus)
- call gsi_bundleputvar ( wbundle, 'uwnd10m', rv_uwnd10m, istatus )
- end if
- if (icvwnd10m>0) then
- call gsi_bundlegetpointer (rval(jj),'vwnd10m' ,rv_vwnd10m, istatus)
- call gsi_bundleputvar ( wbundle, 'vwnd10m', rv_vwnd10m, istatus )
- end if
-
-!$omp end parallel sections
-
-! Adjoint of transfer variables
-
- do ii=1,wbundle%ndim
- grad%step(jj)%values(ii)=wbundle%values(ii)+grad%step(jj)%values(ii)
- enddo
- call gsi_bundledestroy(wbundle,istatus)
- if (istatus/=0) then
- write(6,*) trim(myname),': trouble destroying work bundle'
- call stop2(999)
- endif
-
-end do
-
-! Clean up
-if (ngases>0) deallocate(gases)
-
-if (nclouds>0) deallocate(clouds)
-
-return
-end subroutine control2state_ad
diff --git a/src/gsi/control_vectors.f90 b/src/gsi/control_vectors.f90
index 0847257777..af376995bd 100644
--- a/src/gsi/control_vectors.f90
+++ b/src/gsi/control_vectors.f90
@@ -83,6 +83,7 @@ module control_vectors
use hybrid_ensemble_parameters, only: beta_s0,l_hyb_ens
use hybrid_ensemble_parameters, only: grd_ens
use constants, only : max_varname_length
+use gridmod, only : minmype
use m_rerank, only : rerank
use GSI_BundleMod, only : GSI_BundleCreate
@@ -112,7 +113,7 @@ module control_vectors
public dot_product
public prt_control_norms, axpy, random_cv, setup_control_vectors, &
write_cv, read_cv, inquire_cv, maxval, qdot_prod_sub, init_anacv, &
- final_anacv
+ final_anacv,c2sset_flg,e2sset_flg
!
! Public variables
@@ -157,6 +158,7 @@ module control_vectors
integer(i_kind) :: latlon11,latlon1n,lat2,lon2,nsig,n_ens
integer(i_kind) :: nval_lenz_en
logical,save :: lsqrtb,lcalc_gfdl_cfrac
+logical :: c2sset_flg,e2sset_flg
integer(i_kind) :: m_vec_alloc, max_vec_alloc, m_allocs, m_deallocs
@@ -413,6 +415,8 @@ subroutine init_anacv
write(6,*) myname_,': ALL CONTROL VARIABLES ', nrf_var
end if
lcalc_gfdl_cfrac = .false.
+c2sset_flg = .true. ! set to true in setup. set to false after first (only) call to c2sset
+e2sset_flg = .true. ! set to true in setup. set to false after first (only) call to ensctl2state_set
end subroutine init_anacv
subroutine final_anacv
@@ -889,38 +893,40 @@ real(r_quad) function qdot_prod_sub(xcv,ycv)
end do
endif
else
+ m3d=xcv%step(1)%n3d
+ m2d=xcv%step(1)%n2d
+ itot=max(m3d,0)+max(m2d,0)
+ if(l_hyb_ens)itot=itot+n_ens*naensgrp
+ allocate(partsum(itot))
+ partsum=zero_quad
do ii=1,nsubwin
- m3d=xcv%step(ii)%n3d
- m2d=xcv%step(ii)%n2d
- itot=max(m3d,0)+max(m2d,0)
- if(l_hyb_ens)itot=itot+naensgrp*n_ens
- allocate(partsum(itot))
!$omp parallel do schedule(dynamic,1) private(i)
do i = 1,m3d
- partsum(i) = dplevs(xcv%step(ii)%r3(i)%q,ycv%step(ii)%r3(i)%q,ihalo=1)
+ partsum(i) = partsum(i)+dplevs(xcv%step(ii)%r3(i)%q,ycv%step(ii)%r3(i)%q,ihalo=1)
enddo
!$omp parallel do schedule(dynamic,1) private(i)
do i = 1,m2d
- partsum(m3d+i) = dplevs(xcv%step(ii)%r2(i)%q,ycv%step(ii)%r2(i)%q,ihalo=1)
+ partsum(m3d+i) = partsum(m3d+i)+dplevs(xcv%step(ii)%r2(i)%q,ycv%step(ii)%r2(i)%q,ihalo=1)
enddo
if(l_hyb_ens) then
do ig=1,naensgrp
nigtmp=n_ens*(ig-1)
!$omp parallel do schedule(dynamic,1) private(i)
do i = 1,n_ens
- partsum(m3d+m2d+nigtmp+i) = dplevs(xcv%aens(ii,ig,i)%r3(1)%q,ycv%aens(ii,ig,i)%r3(1)%q,ihalo=1)
+ partsum(m3d+m2d+nigtmp+i) = partsum(m3d+m2d+nigtmp+i) + &
+ dplevs(xcv%aens(ii,ig,i)%r3(1)%q,ycv%aens(ii,ig,i)%r3(1)%q,ihalo=1)
end do
end do
end if
do i=1,itot
qdot_prod_sub = qdot_prod_sub + partsum(i)
end do
- deallocate(partsum)
end do
+ deallocate(partsum)
end if
! Duplicated part of vector
- if(mype == 0)then
+ if(mype == minmype)then
do j=nclen1+1,nclen
qdot_prod_sub=qdot_prod_sub+xcv%values(j)*ycv%values(j)
end do
@@ -966,37 +972,35 @@ subroutine qdot_prod_vars_eb(xcv,ycv,prods,eb)
character(len=*) , intent(in ) :: eb
real(r_quad) , intent( out) :: prods(nsubwin+1)
- real(r_quad) :: zz(nsubwin)
integer(i_kind) :: ii,i,nn,m3d,m2d
real(r_quad),allocatable,dimension(:) :: partsum
integer(i_kind) :: ig
integer(i_kind) ::ngtmp,nn0
prods(:)=zero_quad
- zz(:)=zero_quad
! Independent part of vector
if (lsqrtb) then
if(trim(eb) == 'cost_b') then
do ii=1,nsubwin
- zz(ii)=zz(ii)+qdot_product( xcv%step(ii)%values(:) ,ycv%step(ii)%values(:) )
+ prods(ii)=prods(ii)+qdot_product( xcv%step(ii)%values(:) ,ycv%step(ii)%values(:) )
end do
endif
if(trim(eb) == 'cost_e') then
do ig=1,naensgrp
do nn=1,n_ens
do ii=1,nsubwin
- zz(ii)=zz(ii)+qdot_product( xcv%aens(ii,ig,nn)%values(:) ,ycv%aens(ii,ig,nn)%values(:) )
+ prods(ii)=prods(ii)+qdot_product( xcv%aens(ii,ig,nn)%values(:) ,ycv%aens(ii,ig,nn)%values(:) )
end do
end do
end do
endif
else
if(trim(eb) == 'cost_b') then
+ m3d=xcv%step(1)%n3d
+ m2d=xcv%step(1)%n2d
+ allocate(partsum(m2d+m3d))
do ii=1,nsubwin
- m3d=xcv%step(ii)%n3d
- m2d=xcv%step(ii)%n2d
- allocate(partsum(m2d+m3d))
!$omp parallel do schedule(dynamic,1) private(i)
do i = 1,m3d
partsum(i)= dplevs(xcv%step(ii)%r3(i)%q,ycv%step(ii)%r3(i)%q,ihalo=1)
@@ -1006,17 +1010,17 @@ subroutine qdot_prod_vars_eb(xcv,ycv,prods,eb)
partsum(m3d+i)= dplevs(xcv%step(ii)%r2(i)%q,ycv%step(ii)%r2(i)%q,ihalo=1)
enddo
do i = 1,m2d+m3d
- zz(ii)=zz(ii) + partsum(i)
+ prods(ii)=prods(ii) + partsum(i)
end do
- deallocate(partsum)
end do
+ deallocate(partsum)
end if
if(trim(eb) == 'cost_e') then
- do ii=1,nsubwin ! RTod: somebody could work in opt/zing this ...
- allocate(partsum(n_ens*naensgrp))
+ allocate(partsum(n_ens*naensgrp))
+ do ii=1,nsubwin
+!$omp parallel do schedule(dynamic,1) private(nn,m3d,m2d,ig,ngtmp,nn0)
do ig=1,naensgrp
ngtmp=(ig-1)*n_ens
-!$omp parallel do schedule(dynamic,1) private(nn,m3d,m2d)
do nn=1,n_ens
nn0=nn+ngtmp
partsum(nn0) = zero_quad
@@ -1031,20 +1035,17 @@ subroutine qdot_prod_vars_eb(xcv,ycv,prods,eb)
enddo
end do
do nn=1,n_ens*naensgrp
- zz(ii)=zz(ii)+partsum(nn)
+ prods(ii)=prods(ii)+partsum(nn)
end do
- deallocate(partsum)
end do
+ deallocate(partsum)
end if
end if
- call mpl_allreduce(nsubwin,qpvals=zz)
- prods(1:nsubwin) = zz(1:nsubwin)
-
! Duplicated part of vector
- if(trim(eb) == 'cost_b') then
+ if(mype == minmype .and. trim(eb) == 'cost_b' ) then
if (nsclen>0) then
- prods(nsubwin+1) = prods(nsubwin+1) + qdot_product(xcv%predr(:),ycv%predr(:))
+ prods(nsubwin+1) = qdot_product(xcv%predr(:),ycv%predr(:))
endif
if (npclen>0) then
prods(nsubwin+1) = prods(nsubwin+1) + qdot_product(xcv%predp(:),ycv%predp(:))
@@ -1054,6 +1055,9 @@ subroutine qdot_prod_vars_eb(xcv,ycv,prods,eb)
endif
end if
+ call mpl_allreduce(nsubwin+1,qpvals=prods)
+
+
return
end subroutine qdot_prod_vars_eb
! ----------------------------------------------------------------------
@@ -1226,7 +1230,7 @@ subroutine prt_norms(xcv,sgrep)
zt=sqrt(zt)
if (mype==0) then
- write(6,*)sgrep,' global norm =',real(zt,r_kind)
+ write(6,*)sgrep,' global norm =',zt
endif
!_RT call prt_norms_vars(xcv,sgrep) --->> this routine is hanging
diff --git a/src/gsi/convthin.f90 b/src/gsi/convthin.f90
index cc6d2ed1b5..edac1adbcf 100644
--- a/src/gsi/convthin.f90
+++ b/src/gsi/convthin.f90
@@ -12,7 +12,6 @@ module convthin
!
! subroutines included:
! make3grids
-! map3grids
! map3grids_m ! keep thinned data
! del3grids
!
@@ -31,23 +30,24 @@ module convthin
private
! set subroutines to public
public :: make3grids
- public :: map3grids
public :: map3grids_m
public :: del3grids
! set passed variables to public
public :: use_all
- integer(i_kind):: mlat
+ integer(i_kind):: mlat,itxmax,nlevp
integer(i_kind),allocatable,dimension(:):: mlon
- integer(i_kind),allocatable,dimension(:,:):: icount,icount_fore,icount_aft,ibest_obs,ibest_save
+ logical ,allocatable,dimension(:,:):: icount,icount_fore,icount_aft
+ integer(i_kind),allocatable,dimension(:,:):: ibest_obs,ibest_obs_aft,ibest_obs_fore
real(r_kind),allocatable,dimension(:):: glat
real(r_kind),allocatable,dimension(:,:):: glon,hll,score_crit,score_crit_fore,score_crit_aft
logical use_all
+ logical setfore, setaft, setnormal
contains
- subroutine make3grids(rmesh,nlevp)
+ subroutine make3grids(rmesh,nlevpp)
!$$$ subprogram documentation block
! . . . .
! subprogram: make3grids
@@ -69,7 +69,7 @@ subroutine make3grids(rmesh,nlevp)
! rmesh - mesh size (km) of thinning grid. If (rmesh <= one),
! then no thinning of the data will occur. Instead,
! all data will be used without thinning.
-! nlevp - vertical levels
+! nlevpp - vertical levels
!
! attributes:
! language: f90
@@ -82,12 +82,12 @@ subroutine make3grids(rmesh,nlevp)
implicit none
real(r_kind) ,intent(in ) :: rmesh
- integer(i_kind),intent(in ) :: nlevp
+ integer(i_kind),intent(in ) :: nlevpp
real(r_kind),parameter:: r360 = 360.0_r_kind
integer(i_kind) i,j
- integer(i_kind) mlonx,mlonj,itxmax
+ integer(i_kind) mlonx,mlonj
real(r_kind) dgv,halfpi,dx,dy
real(r_kind) twopi
@@ -95,6 +95,7 @@ subroutine make3grids(rmesh,nlevp)
real(r_kind) rkm2dg,glatm
real(r_quad) delat
+ nlevp=nlevpp
! If there is to be no thinning, simply return to calling routine
use_all=.false.
if(abs(rmesh) <= one)then
@@ -132,7 +133,7 @@ subroutine make3grids(rmesh,nlevp)
factor = abs(cos(abs(glatm)))
if (rmesh>zero) then
- mlonj = nint(mlonx*factor)
+ mlonj = nint(mlonx*factor)
mlon(j) = max(2,mlonj)
delon = dlon_grid/mlon(j)
else
@@ -155,257 +156,108 @@ subroutine make3grids(rmesh,nlevp)
enddo
end do
+ setnormal=.false.
+ setfore=.false.
+ setaft=.false.
-! Allocate and initialize arrays
+ return
+ end subroutine make3grids
+ subroutine createnormal
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: createnormal
+! prgmmr: derber org: np23 date: 2023-10-20
+!
+! abstract: This routine creates and initializes arrays for normal thinning
+!
+! program history log:
+! 2023-10-20 derber
+!
+! attributes:
+! language: f90
+! machine: ibm rs/6000 sp
+!
+!$$$
+ integer i,j
allocate(icount(itxmax,nlevp))
- allocate(icount_fore(itxmax,nlevp))
- allocate(icount_aft(itxmax,nlevp))
allocate(ibest_obs(itxmax,nlevp))
- allocate(ibest_save(itxmax,nlevp))
allocate(score_crit(itxmax,nlevp))
- allocate(score_crit_fore(itxmax,nlevp))
- allocate(score_crit_aft(itxmax,nlevp))
do j=1,nlevp
do i=1,itxmax
- icount(i,j) = 0
- icount_fore(i,j) = 0
- icount_aft(i,j) = 0
+ icount(i,j) = .false.
ibest_obs(i,j)= 0
- ibest_save(i,j)= 0
score_crit(i,j)= 9.99e6_r_kind
- score_crit_fore(i,j) = 9.99e6_r_kind
- score_crit_aft(i,j) = 9.99e6_r_kind
end do
end do
-
+ setnormal=.true.
return
- end subroutine make3grids
-
- subroutine map3grids(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,crit1,iobs,&
- iobsout,iin,iiout,iuse,foreswp,aftswp)
-
+ end subroutine createnormal
+ subroutine createfore
!$$$ subprogram documentation block
! . . . .
-! subprogram: map3grids
-! prgmmr: treadon org: np23 date: 2002-10-17
+! subprogram: createfore
+! prgmmr: derber org: np23 date: 2023-10-20
!
-! abstract: This routine maps convential observations to a 3d thinning grid.
+! abstract: This routine creates and initializes arrays for fore thinning
!
! program history log:
-! 2002-10-17 treadon
-! 2004-06-22 treadon - update documentation
-! 2004-07-23 derber - modify code to thin obs as read in
-! 2004-12-08 li, xu - fix bug --> set iuse=.true. when use_all=.true.
-! 2005-10-14 treadon - variable name change (dlat0,dlon0) --> d*_earth
-! 2006-01-25 kistler - extend 2d to 3d
-! 2008-06-04 safford - rm unused vars
-! 2010-08-23 tong - add flg as an input argument of map3grids, so that the order of values
-! of the vertical cooridnate can either increase or decrease
-! 2012-05-25 li, wang - add TDR fore/aft sweep separation for thinning,xuguang.wang@ou.edu
-! 2013-01-23 parrish - change from grdcrd to grdcrd1 (to allow successful debug compile on WCOSS)
+! 2023-10-20 derber
!
-! input argument list:
-! flg - marks order of values in vertical dirction (1=increasing, -1=decreasing)
-! pflag - type of pressure-type levels; 0 : sigma level, 1 : determined by convinfo file
-! pcoord - veritical coordinate values
-! nlevp - number of vertical levels
-! dlat_earth - earth relative observation latitude (radians)
-! dlon_earth - earth relative observation longitude (radians)
-! pob - observation pressure ob
-! crit1 - quality indicator for observation (smaller = better)
-! iin - counter of input data
-! foreswp - if true, TDR scan is fore
-! aftswp - if true, TDR scan is aft
+! attributes:
+! language: f90
+! machine: ibm rs/6000 sp
!
-! output argument list:
-! iobs - observation counter
-! iobsout- location for observation to be put
-! iuse - .true. if observation should be used
-! iiout - counter of data replaced
-!
+!$$$
+ integer i,j
+ allocate(icount_fore(itxmax,nlevp))
+ allocate(ibest_obs_fore(itxmax,nlevp))
+ allocate(score_crit_fore(itxmax,nlevp))
+
+ do j=1,nlevp
+ do i=1,itxmax
+ icount_fore(i,j) = .false.
+ ibest_obs_fore(i,j)= 0
+ score_crit_fore(i,j)= 9.99e6_r_kind
+ end do
+ end do
+ setfore=.true.
+ return
+ end subroutine createfore
+ subroutine createaft
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: createaft
+! prgmmr: derber org: np23 date: 2023-10-20
+!
+! abstract: This routine creates and initializes arrays for aft thinning
+!
+! program history log:
+! 2023-10-20 derber
!
! attributes:
! language: f90
! machine: ibm rs/6000 sp
!
!$$$
- use constants, only: one, half,two,three
- implicit none
-
- logical ,intent( out) :: iuse
- integer(i_kind) ,intent(in ) :: nlevp,pflag,flg,iin
- integer(i_kind) ,intent(inout) :: iobs
- integer(i_kind) ,intent( out) :: iobsout,iiout
- real(r_kind) ,intent(in ) :: dlat_earth,dlon_earth,crit1,pob
- real(r_kind),dimension(nlevp),intent(in ) :: pcoord
-
- integer(i_kind):: ip,itx
- integer(i_kind) ix,iy
-
- real(r_kind) dlat1,dlon1,pob1
- real(r_kind) dx,dy,dp,dxx,dyy,dpp
- real(r_kind) crit!,dist1
-
- logical foreswp, aftswp
-
- iiout = 0
-
-! If using all data (no thinning), simply return to calling routine
- if(use_all)then
- iuse=.true.
- iobs=iobs+1
- iobsout=iobs
- return
- end if
-
-! Compute (i,j,k) indices of coarse mesh grid (grid number 1) which
-! contains the current observation.
- dlat1=dlat_earth
- dlon1=dlon_earth
- pob1=pob
-
- call grdcrd1(pob1,pcoord,nlevp,flg)
- ip=int(pob1)
- dp=pob1-ip
- ip=max(1,min(ip,nlevp))
-
- call grdcrd1(dlat1,glat,mlat,1)
- iy=int(dlat1)
- dy=dlat1-iy
- iy=max(1,min(iy,mlat))
-
- call grdcrd1(dlon1,glon(1,iy),mlon(iy),1)
- ix=int(dlon1)
- dx=dlon1-ix
- ix=max(1,min(ix,mlon(iy)))
-
- dxx=half-min(dx,one-dx)
- dyy=half-min(dy,one-dy)
- if( pflag == 1) then
- dpp=half-min(dp,one-dp)
- else
- dpp=min(dp,one-dp)
- endif
-
- itx=hll(ix,iy)
-
-! Compute distance metric (smaller is closer to center of cube)
-! dist1=(dxx*dxx+dyy*dyy+dpp*dpp)*two/three+half
-
-
-! Examine various cases regarding what to do with current obs.
-! Start by assuming observation will be selected.
- iuse=.true.
-
-! Determine "score" for observation. Lower score is better.
-! crit = crit1*dist1
- crit = crit1
-
-
-! TDR fore (Pseudo-dual-Doppler-radars)
-
- if(foreswp) then ! fore sweeps
-
-! Case(1): first obs at this location, keep this obs as starting point
- if (icount_fore(itx,ip)==0) then
- iobs=iobs+1
- iobsout=iobs
- score_crit_fore(itx,ip)= crit
- icount_fore(itx,ip)=icount_fore(itx,ip)+1
- ibest_obs(itx,ip) = iobs
- ibest_save(itx,ip) = iin
-
-! Case(2): obs score < best value at this location,
-! --> update score, count, and best obs counters
- elseif (icount_fore(itx,ip) > 0 .and. crit < score_crit_fore(itx,ip)) then
- score_crit_fore(itx,ip)= crit
- icount_fore(itx,ip)=icount_fore(itx,ip)+1
- iobsout=ibest_obs(itx,ip)
- iiout = ibest_save(itx,ip)
- ibest_save(itx,ip)=iin
-
-! Case(3): obs score > best value at this location,
-! --> do not use this obs, return to calling program.
- elseif (icount_fore(itx,ip) > 0 .and. crit > score_crit_fore(itx,ip)) then
- iuse=.false.
-
-! Case(4): none of the above cases are satisified, don't use this obs
- else
- iuse = .false.
- endif ! cases
-
-! TDR aft (Pseudo-dual-Doppler-radars)
- else if(aftswp) then ! aft sweeps
-
-! Case(1): first obs at this location, keep this obs as starting point
- if (icount_aft(itx,ip)==0) then
- iobs=iobs+1
- iobsout=iobs
- score_crit_aft(itx,ip)= crit
- icount_aft(itx,ip)=icount_aft(itx,ip)+1
- ibest_obs(itx,ip) = iobs
- ibest_save(itx,ip) = iin
-
-
-! Case(2): obs score < best value at this location,
-! --> update score, count, and best obs counters
- elseif (icount_aft(itx,ip) > 0 .and. crit < score_crit_aft(itx,ip)) then
- score_crit_aft(itx,ip)= crit
- icount_aft(itx,ip)=icount_aft(itx,ip)+1
- iobsout=ibest_obs(itx,ip)
- iiout = ibest_save(itx,ip)
- ibest_save(itx,ip)=iin
-
-! Case(3): obs score > best value at this location,
-! --> do not use this obs, return to calling program.
- elseif(icount_aft(itx,ip) > 0 .and. crit > score_crit_aft(itx,ip)) then
- iuse=.false.
-
-! Case(4): none of the above cases are satisified,
-! --> don't use this obs
- else
- iuse = .false.
- endif ! cases
-
- else
-! Case: obs score > best value at this location,
-! --> do not use this obs, return to calling program.
- if(crit > score_crit(itx,ip) .and. icount(itx,ip) > 0) then
- iuse=.false.
-
-! Case: obs score < best value at this location,
-! --> update score, count, and best obs counters
- elseif (icount(itx,ip) > 0 .and. crit < score_crit(itx,ip)) then
- score_crit(itx,ip)= crit
- iobsout=ibest_obs(itx,ip)
- icount(itx,ip)=icount(itx,ip)+1
- iiout = ibest_save(itx,ip)
- ibest_save(itx,ip)=iin
-
-! Case: first obs at this location,
-! --> keep this obs as starting point
- elseif (icount(itx,ip)==0) then
- iobs=iobs+1
- iobsout=iobs
- score_crit(itx,ip)= crit
- ibest_obs(itx,ip) = iobs
- icount(itx,ip)=icount(itx,ip)+1
- ibest_save(itx,ip) = iin
-
-! Case: none of the above cases are satisified,
-! --> don't use this obs
- else
- iuse = .false.
- end if
- end if
- return
-
+ integer i,j
+ allocate(icount_aft(itxmax,nlevp))
+ allocate(ibest_obs_aft(itxmax,nlevp))
+ allocate(score_crit_aft(itxmax,nlevp))
- end subroutine map3grids
+ do j=1,nlevp
+ do i=1,itxmax
+ icount_aft(i,j) = .false.
+ ibest_obs_aft(i,j)= 0
+ score_crit_aft(i,j)= 9.99e6_r_kind
+ end do
+ end do
+ setaft=.true.
+ return
+ end subroutine createaft
- subroutine map3grids_m(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,crit1,iobs,&
- iobsout,iin,iiout,iuse,maxobs,usage,rusage,foreswp,aftswp)
+ subroutine map3grids_m(flg,save_all,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,crit1,iobs,&
+ iuse,maxobs,rthin,foreswp,aftswp)
!$$$ subprogram documentation block
! . . . .
@@ -434,9 +286,11 @@ subroutine map3grids_m(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,crit1,io
!
! input argument list:
! flg - marks order of values in vertical dirction (1=increasing,
-! -1=decreasing)
+! -1=decreasing)
+! save_all - logical - if true save all obs. (if false some unused values
+! still get through)
! pflag - type of pressure-type levels; 0 : sigma level, 1 : determined by
-! convinfo file
+! convinfo file
! pcoord - veritical coordinate values
! nlevp - number of vertical levels
! dlat_earth - earth relative observation latitude (radians)
@@ -444,15 +298,12 @@ subroutine map3grids_m(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,crit1,io
! pob - observation pressure ob
! crit1 - quality indicator for observation (smaller = better)
! ithin - number of obs to retain per thinning grid box
-! iin - counter of input data
! foreswp - if true, TDR scan is fore
! aftswp - if true, TDR scan is aft
!
! output argument list:
! iobs - observation counter
-! iobsout- location for observation to be put
! iuse - .true. if observation should be used
-! iiout - counter of data replaced
! attributes:
! language: f90
! machine: ibm rs/6000 sp
@@ -462,30 +313,27 @@ subroutine map3grids_m(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,crit1,io
implicit none
logical ,intent( out) :: iuse
- integer(i_kind) ,intent(in ) :: nlevp,pflag,flg,iin,maxobs
+ logical ,intent(in ) :: save_all
+ integer(i_kind) ,intent(in ) :: nlevp,pflag,flg,maxobs
integer(i_kind) ,intent(inout) :: iobs
- integer(i_kind) ,intent( out) :: iobsout,iiout
- real(r_kind) ,intent(in ) :: dlat_earth,dlon_earth,crit1,pob,usage
+ real(r_kind) ,intent(in ) :: dlat_earth,dlon_earth,crit1,pob
real(r_kind),dimension(nlevp),intent(in ) :: pcoord
- real(r_kind),dimension(maxobs),intent(inout ) :: rusage
+ logical,dimension(maxobs), intent(inout) :: rthin
integer(i_kind):: ip,itx
- integer(i_kind) ix,iy
+ integer(i_kind) ix,iy,itmp
real(r_kind) dlat1,dlon1,pob1
- real(r_kind) dx,dy,dp,dxx,dyy,dpp
- real(r_kind) crit!,dist1
+ real(r_kind) dx,dy,dp
+ real(r_kind) crit !,dist1
logical foreswp, aftswp
- iiout = 0
+ iuse=.true.
! If using all data (no thinning), simply return to calling routine
if(use_all)then
- iuse=.true.
iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=usage
return
end if
@@ -510,13 +358,13 @@ subroutine map3grids_m(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,crit1,io
dx=dlon1-ix
ix=max(1,min(ix,mlon(iy)))
- dxx=half-min(dx,one-dx)
- dyy=half-min(dy,one-dy)
- if( pflag == 1) then
- dpp=half-min(dp,one-dp)
- else
- dpp=min(dp,one-dp)
- endif
+! dxx=half-min(dx,one-dx)
+! dyy=half-min(dy,one-dy)
+! if( pflag == 1) then
+! dpp=half-min(dp,one-dp)
+! else
+! dpp=min(dp,one-dp)
+! endif
itx=hll(ix,iy)
@@ -526,7 +374,6 @@ subroutine map3grids_m(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,crit1,io
! Examine various cases regarding what to do with current obs.
! Start by assuming observation will be selected.
- iuse=.true.
! Determine "score" for observation. Lower score is better.
! crit = crit1*dist1
@@ -534,127 +381,95 @@ subroutine map3grids_m(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,crit1,io
! TDR fore/aft (Pseudo-dual-Doppler-radars)
if(foreswp) then ! fore sweeps
+ if(.not. setfore)call createfore
! Case(1): first obs at this location, keep this obs as starting point
- if (icount_fore(itx,ip)==0) then
+ if (.not. icount_fore(itx,ip)) then
iobs=iobs+1
- iobsout=iobs
score_crit_fore(itx,ip)= crit
- icount_fore(itx,ip)=icount_fore(itx,ip)+1
- ibest_obs(itx,ip) = iobs
- rusage(iobs)=usage
- ibest_save(itx,ip)=iin
+ icount_fore(itx,ip)=.true.
+ ibest_obs_fore(itx,ip) = iobs
! Case(2): obs score < best value at this location,
! --> update score, count, and best obs counters
- elseif (icount_fore(itx,ip) > 0 .and. crit < score_crit_fore(itx,ip)) then
+ elseif (icount_fore(itx,ip) .and. crit < score_crit_fore(itx,ip)) then
iobs=iobs+1
- iobsout=iobs
- score_crit(itx,ip)= crit
-! iobsout=ibest_obs(itx,ip)
- icount(itx,ip)=icount(itx,ip)+1
- iiout = ibest_save(itx,ip)
- rusage(iiout)=101.0_r_kind
- rusage(iobs)=usage
- ibest_save(itx,ip)=iobs
+ itmp=ibest_obs_fore(itx,ip)
+ rthin(itmp)=.true.
+ score_crit_fore(itx,ip)= crit
+ ibest_obs_fore(itx,ip)=iobs
! Case(3): obs score > best value at this location,
! --> do not use this obs, return to calling program.
- elseif (icount_fore(itx,ip) > 0 .and. crit > score_crit_fore(itx,ip)) then
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.1_r_kind
- iuse=.false.
-
-! Case(4): none of the above cases are satisified, don't use this obs
else
- iuse = .false.
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.1_r_kind
+ if(save_all)then
+ iobs=iobs+1
+ rthin(iobs)=.true.
+ else
+ iuse=.false.
+ end if
endif ! cases
else if(aftswp) then ! aft sweeps
+ if(.not. setaft)call createaft
! Case(1): first obs at this location, keep this obs as starting point
- if (icount_aft(itx,ip)==0) then
+ if (.not. icount_aft(itx,ip)) then
iobs=iobs+1
- iobsout=iobs
score_crit_aft(itx,ip)= crit
- icount_aft(itx,ip)=icount_aft(itx,ip)+1
- ibest_obs(itx,ip) = iobs
- ibest_save(itx,ip) = iin
+ icount_aft(itx,ip)=.true.
+ ibest_obs_aft(itx,ip) = iobs
! Case(2): obs score < best value at this location,
! --> update score, count, and best obs counters
- elseif (icount_aft(itx,ip) > 0 .and. crit < score_crit_aft(itx,ip)) then
+ elseif (icount_aft(itx,ip) .and. crit < score_crit_aft(itx,ip)) then
iobs=iobs+1
- iobsout=iobs
+ itmp=ibest_obs_aft(itx,ip)
+ rthin(itmp)=.true.
score_crit_aft(itx,ip)= crit
- icount_aft(itx,ip)=icount_aft(itx,ip)+1
- iobsout=ibest_obs(itx,ip)
- iiout = ibest_save(itx,ip)
- ibest_save(itx,ip)=iobs
- rusage(iobs)=usage
+ ibest_obs_aft(itx,ip)=iobs
! Case(3): obs score > best value at this location,
! --> do not use this obs, return to calling program.
- elseif(icount_aft(itx,ip) > 0 .and. crit > score_crit_aft(itx,ip)) then
- iuse=.false.
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.1_r_kind
-
-! Case(4): none of the above cases are satisified,
-! --> don't use this obs
else
- iuse = .false.
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.1_r_kind
+ if(save_all)then
+ iobs=iobs+1
+ rthin(iobs)=.true.
+ else
+ iuse=.false.
+ end if
endif ! cases
else
-! Case: obs score > best value at this location,
-! --> do not use this obs, return to calling program.
- if(crit > score_crit(itx,ip) .and. icount(itx,ip) > 0) then
- iuse=.false.
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.0_r_kind
+ if(.not. setnormal)call createnormal
! Case: obs score < best value at this location,
! --> update score, count, and best obs counters
- elseif (icount(itx,ip) > 0 .and. crit < score_crit(itx,ip)) then
+ if (icount(itx,ip) .and. crit < score_crit(itx,ip)) then
iobs=iobs+1
- iobsout=iobs
+ itmp=ibest_obs(itx,ip)
+ rthin(itmp)=.true.
score_crit(itx,ip)= crit
- icount(itx,ip)=icount(itx,ip)+1
- iiout = ibest_obs(itx,ip)
- ibest_save(itx,ip)=iin
ibest_obs(itx,ip)=iobs
- rusage(iiout)=101.0_r_kind
- rusage(iobs)=usage
! Case: first obs at this location,
! --> keep this obs as starting point
- elseif (icount(itx,ip)==0) then
+ elseif (.not. icount(itx,ip)) then
iobs=iobs+1
- iobsout=iobs
score_crit(itx,ip)= crit
- ibest_obs(itx,ip) = iobs
- icount(itx,ip)=icount(itx,ip)+1
- ibest_save(itx,ip) = iin
- rusage(iobs)=usage
+ ibest_obs(itx,ip)=iobs
+ icount(itx,ip)=.true.
-! Case: none of the above cases are satisified,
-! --> don't use this obs
+! Case: obs score > best value at this location,
+! --> do not use this obs, return to calling program.
else
- iuse = .false.
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.0_r_kind
+ if(save_all)then
+ iobs=iobs+1
+ rthin(iobs)=.true.
+ else
+ iuse=.false.
+ end if
end if
end if
return
@@ -662,8 +477,6 @@ subroutine map3grids_m(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,crit1,io
end subroutine map3grids_m
-
-
subroutine del3grids
!$$$ subprogram documentation block
! . . . .
@@ -689,14 +502,24 @@ subroutine del3grids
if (.not.use_all) then
deallocate(mlon,glat,glon,hll)
- deallocate(icount)
- deallocate(icount_fore)
- deallocate(icount_aft)
- deallocate(ibest_obs)
- deallocate(ibest_save)
- deallocate(score_crit)
- deallocate(score_crit_fore)
- deallocate(score_crit_aft)
+ if(setnormal)then
+ deallocate(icount)
+ deallocate(ibest_obs)
+ deallocate(score_crit)
+ setnormal=.false.
+ end if
+ if(setfore)then
+ deallocate(icount_fore)
+ deallocate(score_crit_fore)
+ deallocate(ibest_obs_fore)
+ setfore=.false.
+ end if
+ if(setaft)then
+ deallocate(icount_aft)
+ deallocate(ibest_obs_aft)
+ deallocate(score_crit_aft)
+ setaft=.false.
+ end if
endif
end subroutine del3grids
diff --git a/src/gsi/convthin_time.f90 b/src/gsi/convthin_time.f90
index 36ab178393..ae2a7bb6c3 100644
--- a/src/gsi/convthin_time.f90
+++ b/src/gsi/convthin_time.f90
@@ -8,7 +8,6 @@ module convthin_time
!
! subroutines included:
! make3grids_tm
-! map3grids_tm
! map3grids_m_tm
! del3grids_tm
!
@@ -27,24 +26,25 @@ module convthin_time
private
! set subroutines to public
public :: make3grids_tm
- public :: map3grids_tm
public :: map3grids_m_tm
public :: del3grids_tm
! set passed variables to public
public :: use_all_tm
- integer(i_kind):: mlat
+ integer(i_kind):: mlat,nlevp,ntm,itxmax
integer(i_kind),allocatable,dimension(:):: mlon
- integer(i_kind),allocatable,dimension(:,:,:):: icount_tm,icount_fore_tm,icount_aft_tm,ibest_obs_tm,ibest_save_tm
+ logical ,allocatable,dimension(:,:,:):: icount_tm,icount_fore_tm,icount_aft_tm
+ integer(i_kind),allocatable,dimension(:,:,:):: ibest_obs_tm,ibest_obs_aft_tm,ibest_obs_fore_tm
real(r_kind),allocatable,dimension(:):: glat
real(r_kind),allocatable,dimension(:,:):: glon,hll
real(r_kind),allocatable,dimension(:,:,:):: score_crit_tm,score_crit_fore_tm,score_crit_aft_tm
logical use_all_tm
+ logical setfore,setaft,setnormal
contains
- subroutine make3grids_tm(rmesh,nlevp,ntm)
+ subroutine make3grids_tm(rmesh,nlevpp,ntmm)
!$$$ subprogram documentation block
! . . . .
! subprogram: make3grids_tm
@@ -59,8 +59,8 @@ subroutine make3grids_tm(rmesh,nlevp,ntm)
! rmesh - mesh size (km) of thinning grid. If (rmesh <= one),
! then no thinning of the data will occur. Instead,
! all data will be used without thinning.
-! nlevp - vertical levels
-! ntm - tm dimension relative to analysis tm
+! nlevpp - vertical levels
+! ntmm - tm dimension relative to analysis tm
!
! attributes:
! language: f90
@@ -73,13 +73,13 @@ subroutine make3grids_tm(rmesh,nlevp,ntm)
implicit none
real(r_kind) ,intent(in ) :: rmesh
- integer(i_kind),intent(in ) :: nlevp
- integer(i_kind),intent(in ) :: ntm
+ integer(i_kind),intent(in ) :: nlevpp
+ integer(i_kind),intent(in ) :: ntmm
real(r_kind),parameter:: r360 = 360.0_r_kind
- integer(i_kind) i,j,it
- integer(i_kind) mlonx,mlonj,itxmax
+ integer(i_kind) i,j
+ integer(i_kind) mlonx,mlonj
real(r_kind) delonx,delat,dgv,halfpi,dx,dy
real(r_kind) twopi
@@ -95,6 +95,8 @@ subroutine make3grids_tm(rmesh,nlevp,ntm)
end if
! Set constants
+ ntm=ntmm
+ nlevp=nlevpp
halfpi = half*pi
twopi = two*pi
rkm2dg = r360/(twopi*rearth_equator)*1.e3_r_kind
@@ -124,7 +126,7 @@ subroutine make3grids_tm(rmesh,nlevp,ntm)
factor = abs(cos(abs(glatm)))
if (rmesh>zero) then
- mlonj = nint(mlonx*factor)
+ mlonj = nint(mlonx*factor)
mlon(j) = max(2,mlonj)
delon = dlon_grid/mlon(j)
else
@@ -145,246 +147,114 @@ subroutine make3grids_tm(rmesh,nlevp,ntm)
end do
! Allocate and initialize arrays
+ setnormal=.false.
+ setfore=.false.
+ setaft=.false.
+
+ return
+ end subroutine make3grids_tm
+ subroutine createnormal_tm
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: createnormal
+! prgmmr: derber org: np23 date: 2023-10-20
+!
+! abstract: This routine creates and initializes arrays for normal thinning
+!
+! program history log:
+! 2023-10-20 derber
+!
+! attributes:
+! language: f90
+! machine: ibm rs/6000 sp
+!
+!$$$
+ integer i,j,it
allocate(icount_tm(itxmax,nlevp,ntm))
- allocate(icount_fore_tm(itxmax,nlevp,ntm))
- allocate(icount_aft_tm(itxmax,nlevp,ntm))
allocate(ibest_obs_tm(itxmax,nlevp,ntm))
- allocate(ibest_save_tm(itxmax,nlevp,ntm))
allocate(score_crit_tm(itxmax,nlevp,ntm))
- allocate(score_crit_fore_tm(itxmax,nlevp,ntm))
- allocate(score_crit_aft_tm(itxmax,nlevp,ntm))
do j=1,nlevp
do i=1,itxmax
do it=1,ntm
- icount_tm(i,j,it) = 0
- icount_fore_tm(i,j,it) = 0
- icount_aft_tm(i,j,it) = 0
+ icount_tm(i,j,it) = .false.
ibest_obs_tm(i,j,it)= 0
- ibest_save_tm(i,j,it)= 0
score_crit_tm(i,j,it)= 9.99e6_r_kind
- score_crit_fore_tm(i,j,it)= 9.99e6_r_kind
- score_crit_aft_tm(i,j,it)= 9.99e6_r_kind
end do
end do
end do
-
+ setnormal=.true.
return
- end subroutine make3grids_tm
-
- subroutine map3grids_tm(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,&
- pob,itm,crit1,iobs,iobsout,iin,iiout,iuse,foreswp,aftswp)
-
+ end subroutine createnormal_tm
+ subroutine createfore_tm
!$$$ subprogram documentation block
! . . . .
-! subprogram: map3grids_tm
-! prgmmr: Su org: np23 date: 2013-11-20
+! subprogram: createfore_tm
+! prgmmr: derber org: np23 date: 2023-10-20
!
-! abstract: This routine maps convential observations to a 3d thinning grid.
+! abstract: This routine creates and initializes arrays for fore thinning
!
! program history log:
+! 2023-10-20 derber
!
-! input argument list:
-! flg - marks order of values in vertical dirction (1=increasing, -1=decreasing)
-! pflag - type of pressure-type levels; 0 : sigma level, 1 : determined by convinfo file
-! pcoord - veritical coordinate values
-! nlevp - number of vertical levels
-! dlat_earth - earth relative observation latitude (radians)
-! dlon_earth - earth relative observation longitude (radians)
-! pob - observation pressure ob
-! crit1 - quality indicator for observation (smaller = better)
-! ithin - number of obs to retain per thinning grid box
-! iin - counter of input data
-! itm - tm count
+! attributes:
+! language: f90
+! machine: ibm rs/6000 sp
!
-! output argument list:
-! iobs - observation counter
-! itx - combined (i,j) index of observation on thinning grid
-! iobsout- location for observation to be put
-! ip - vertical index
-! iuse - .true. if observation should be used
-! iiout - counter of data replaced
-!
+!$$$
+ integer i,j,it
+ allocate(icount_fore_tm(itxmax,nlevp,ntm))
+ allocate(ibest_obs_fore_tm(itxmax,nlevp,ntm))
+ allocate(score_crit_fore_tm(itxmax,nlevp,ntm))
+
+ do j=1,nlevp
+ do i=1,itxmax
+ do it=1,ntm
+ icount_fore_tm(i,j,it) = .false.
+ ibest_obs_fore_tm(i,j,it)= 0
+ score_crit_fore_tm(i,j,it)= 9.99e6_r_kind
+ end do
+ end do
+ end do
+ setfore=.true.
+ return
+ end subroutine createfore_tm
+ subroutine createaft_tm
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: createaft
+! prgmmr: derber org: np23 date: 2023-10-20
+!
+! abstract: This routine creates and initializes arrays for aft thinning
+!
+! program history log:
+! 2023-10-20 derber
!
! attributes:
! language: f90
! machine: ibm rs/6000 sp
!
!$$$
- use constants, only: one, half,two,three
- implicit none
-
- logical ,intent( out) :: iuse
- integer(i_kind) ,intent(in ) :: nlevp,pflag,flg,iin,itm
- integer(i_kind) ,intent(inout) :: iobs
- integer(i_kind) ,intent( out) :: iobsout,iiout
- real(r_kind) ,intent(in ) :: dlat_earth,dlon_earth,crit1,pob
-
- real(r_kind),dimension(nlevp),intent(in ) :: pcoord
-
- integer(i_kind):: ip,itx
- integer(i_kind) ix,iy
-
- real(r_kind) dlat1,dlon1,pob1
- real(r_kind) dx,dy,dp,dxx,dyy,dpp
- real(r_kind) crit!,dist1
- logical foreswp, aftswp
-
-
- iiout = 0
-
-! If using all data (no thinning), simply return to calling routine
- if(use_all_tm)then
- iuse=.true.
- iobs=iobs+1
- iobsout=iobs
- return
- end if
-
-! Compute (i,j,k) indices of coarse mesh grid (grid number 1) which
-! contains the current observation.
- dlat1=dlat_earth
- dlon1=dlon_earth
- pob1=pob
-
- call grdcrd1(pob1,pcoord,nlevp,flg)
- ip=int(pob1)
- dp=pob1-ip
- ip=max(1,min(ip,nlevp))
-
- call grdcrd1(dlat1,glat,mlat,1)
- iy=int(dlat1)
- dy=dlat1-iy
- iy=max(1,min(iy,mlat))
-
- call grdcrd1(dlon1,glon(1,iy),mlon(iy),1)
- ix=int(dlon1)
- dx=dlon1-ix
- ix=max(1,min(ix,mlon(iy)))
-
- dxx=half-min(dx,one-dx)
- dyy=half-min(dy,one-dy)
- if( pflag == 1) then
- dpp=half-min(dp,one-dp)
- else
- dpp=min(dp,one-dp)
- endif
-
- itx=hll(ix,iy)
-
-! Compute distance metric (smaller is closer to center of cube)
-! dist1=(dxx*dxx+dyy*dyy+dpp*dpp)*two/three+half
-
-
-! Examine various cases regarding what to do with current obs.
-! Start by assuming observation will be selected.
- iuse=.true.
-
-! Determine "score" for observation. Lower score is better.
-! crit = crit1*dist1
- crit = crit1
-
-! TDR fore (Pseudo-dual-Doppler-radars)
- if(foreswp) then ! fore sweeps
-
-! Case(1): first obs at this location, keep this obs as starting point
- if (icount_fore_tm(itx,ip,itm)==0) then
- iobs=iobs+1
- iobsout=iobs
- score_crit_fore_tm(itx,ip,itm)= crit
- icount_fore_tm(itx,ip,itm)=icount_fore_tm(itx,ip,itm)+1
- ibest_obs_tm(itx,ip,itm) = iobs
- ibest_save_tm(itx,ip,itm) = iin
-
-! Case(2): obs score < best value at this location,
-! --> update score, count, and best obs counters
- elseif (icount_fore_tm(itx,ip,itm) > 0 .and. crit < score_crit_fore_tm(itx,ip,itm)) then
- score_crit_fore_tm(itx,ip,itm)= crit
- icount_fore_tm(itx,ip,itm)=icount_fore_tm(itx,ip,itm)+1
- iobsout=ibest_obs_tm(itx,ip,itm)
- iiout = ibest_save_tm(itx,ip,itm)
- ibest_save_tm(itx,ip,itm)=iin
-
-! Case(3): obs score > best value at this location,
-! --> do not use this obs, return to calling program.
- elseif (icount_fore_tm(itx,ip,itm) > 0 .and. crit > score_crit_fore_tm(itx,ip,itm)) then
- iuse=.false.
-! Case(4): none of the above cases are satisified, don't use this obs
- else
- iuse = .false.
- endif ! cases
-
-! TDR aft (Pseudo-dual-Doppler-radars)
- else if(aftswp) then ! aft sweeps
-
-! Case(1): first obs at this location, keep this obs as starting point
- if (icount_aft_tm(itx,ip,itm)==0) then
- iobs=iobs+1
- iobsout=iobs
- score_crit_aft_tm(itx,ip,itm)= crit
- icount_aft_tm(itx,ip,itm)=icount_aft_tm(itx,ip,itm)+1
- ibest_obs_tm(itx,ip,itm) = iobs
- ibest_save_tm(itx,ip,itm) = iin
-
-
-! Case(2): obs score < best value at this location,
-! --> update score, count, and best obs counters
- elseif (icount_aft_tm(itx,ip,itm) > 0 .and. crit < score_crit_aft_tm(itx,ip,itm)) then
- score_crit_aft_tm(itx,ip,itm)= crit
- icount_aft_tm(itx,ip,itm)=icount_aft_tm(itx,ip,itm)+1
- iobsout=ibest_obs_tm(itx,ip,itm)
- iiout = ibest_save_tm(itx,ip,itm)
- ibest_save_tm(itx,ip,itm)=iin
-
-! Case(3): obs score > best value at this location,
-! --> do not use this obs, return to calling program.
- elseif(icount_aft_tm(itx,ip,itm) > 0 .and. crit > score_crit_aft_tm(itx,ip,itm)) then
- iuse=.false.
-
-! Case(4): none of the above cases are satisified,
-! --> don't use this obs
- else
- iuse = .false.
- endif ! cases
-
- else
-! Case: obs score > best value at this location,
-! --> do not use this obs, return to calling program.
- if(crit > score_crit_tm(itx,ip,itm) .and. icount_tm(itx,ip,itm) > 0) then
- iuse=.false.
-
-! Case: obs score < best value at this location,
-! --> update score, count, and best obs counters
- elseif (icount_tm(itx,ip,itm) > 0 .and. crit < score_crit_tm(itx,ip,itm)) then
- score_crit_tm(itx,ip,itm)= crit
- iobsout=ibest_obs_tm(itx,ip,itm)
- icount_tm(itx,ip,itm)=icount_tm(itx,ip,itm)+1
- iiout = ibest_save_tm(itx,ip,itm)
- ibest_save_tm(itx,ip,itm)=iin
-
-! Case: first obs at this location,
-! --> keep this obs as starting point
- elseif (icount_tm(itx,ip,itm)==0) then
- iobs=iobs+1
- iobsout=iobs
- score_crit_tm(itx,ip,itm)= crit
- ibest_obs_tm(itx,ip,itm) = iobs
- icount_tm(itx,ip,itm)=icount_tm(itx,ip,itm)+1
- ibest_save_tm(itx,ip,itm) = iin
-
-! Case: none of the above cases are satisified,
-! --> don't use this obs
- else
- iuse = .false.
- end if
- end if
+ integer i,j,it
+ allocate(icount_aft_tm(itxmax,nlevp,ntm))
+ allocate(ibest_obs_aft_tm(itxmax,nlevp,ntm))
+ allocate(score_crit_aft_tm(itxmax,nlevp,ntm))
+ do j=1,nlevp
+ do i=1,itxmax
+ do it=1,ntm
+ icount_aft_tm(i,j,it) = .false.
+ ibest_obs_aft_tm(i,j,it)= 0
+ score_crit_aft_tm(i,j,it)= 9.99e6_r_kind
+ end do
+ end do
+ end do
+ setaft=.true.
return
+ end subroutine createaft_tm
- end subroutine map3grids_tm
-
- subroutine map3grids_m_tm(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,itm,crit1,iobs,&
- iobsout,iin,iiout,iuse,maxobs,usage,rusage,foreswp,aftswp)
+ subroutine map3grids_m_tm(flg,save_all,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,itm,crit1,iobs,&
+ iuse,maxobs,rthin,foreswp,aftswp)
!$$$ subprogram documentation block
! . . . .
! subprogram: map3grids_m_tm
@@ -415,16 +285,14 @@ subroutine map3grids_m_tm(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,itm,c
! pob - observation pressure ob
! crit1 - quality indicator for observation (smaller = better)
! ithin - number of obs to retain per thinning grid box
-! iin - counter of input data
+! save_all - flag to save all data (if false, some unused data will still
+ ! be saved.
!
! output argument list:
! iobs - observation counter
! itx - combined (i,j) index of observation on thinning grid
-! iobsout- location for observation to be put
! ip - vertical index
! iuse - .true. if observation should be used
-! iiout - counter of data replaced
-! usage - data usage flag, 0 to keep, 101.0 not to keep
!
!
! attributes:
@@ -436,30 +304,27 @@ subroutine map3grids_m_tm(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,itm,c
implicit none
logical ,intent( out) :: iuse
- integer(i_kind) ,intent(in ) :: nlevp,pflag,flg,iin,maxobs,itm
+ logical ,intent(in ) :: save_all
+ integer(i_kind) ,intent(in ) :: nlevp,pflag,flg,maxobs,itm
integer(i_kind) ,intent(inout) :: iobs
- integer(i_kind) ,intent( out) :: iobsout,iiout
- real(r_kind) ,intent(in ) :: dlat_earth,dlon_earth,crit1,pob,usage
+ real(r_kind) ,intent(in ) :: dlat_earth,dlon_earth,crit1,pob
real(r_kind),dimension(nlevp),intent(in ) :: pcoord
- real(r_kind),dimension(maxobs),intent(inout ) :: rusage
+ logical,dimension(maxobs) ,intent(inout) :: rthin
integer(i_kind):: ip,itx
- integer(i_kind) ix,iy
+ integer(i_kind) ix,iy,itmp
real(r_kind) dlat1,dlon1,pob1
- real(r_kind) dx,dy,dp,dxx,dyy,dpp
+ real(r_kind) dx,dy,dp
+! real(r_kind) dxx,dyy,dpp
real(r_kind) crit!,dist1
logical foreswp, aftswp
- iiout = 0
-
+ iuse=.true.
! If using all data (no thinning), simply return to calling routine
if(use_all_tm)then
- iuse=.true.
iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=usage
return
end if
@@ -484,13 +349,13 @@ subroutine map3grids_m_tm(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,itm,c
dx=dlon1-ix
ix=max(1,min(ix,mlon(iy)))
- dxx=half-min(dx,one-dx)
- dyy=half-min(dy,one-dy)
- if( pflag == 1) then
- dpp=half-min(dp,one-dp)
- else
- dpp=min(dp,one-dp)
- endif
+! dxx=half-min(dx,one-dx)
+! dyy=half-min(dy,one-dy)
+! if( pflag == 1) then
+! dpp=half-min(dp,one-dp)
+! else
+! dpp=min(dp,one-dp)
+! endif
itx=hll(ix,iy)
@@ -500,7 +365,6 @@ subroutine map3grids_m_tm(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,itm,c
! Examine various cases regarding what to do with current obs.
! Start by assuming observation will be selected.
- iuse=.true.
! Determine "score" for observation. Lower score is better.
! crit = crit1*dist1
@@ -508,129 +372,98 @@ subroutine map3grids_m_tm(flg,pflag,pcoord,nlevp,dlat_earth,dlon_earth,pob,itm,c
! TDR fore (Pseudo-dual-Doppler-radars)
if(foreswp) then ! fore sweeps
-! Case: obs score > best value at this location,
-! --> do not use this obs, return to calling program.
- if(crit > score_crit_fore_tm(itx,ip,itm) .and. icount_fore_tm(itx,ip,itm) > 0) then
- iuse=.false.
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.1_r_kind
-
+ if(.not.setfore)call createfore_tm
! Case: obs score < best value at this location,
! --> update score, count, and best obs counters
- elseif (icount_fore_tm(itx,ip,itm) > 0 .and. crit < score_crit_fore_tm(itx,ip,itm)) then
+ if (icount_fore_tm(itx,ip,itm) .and. crit < score_crit_fore_tm(itx,ip,itm)) then
iobs=iobs+1
- iobsout=iobs
+ itmp=ibest_obs_fore_tm(itx,ip,itm)
+ rthin(itmp)=.true.
+ ibest_obs_fore_tm(itx,ip,itm)=iobs
score_crit_fore_tm(itx,ip,itm)= crit
-! iobsout=ibest_obs_tm(itx,ip)
- icount_fore_tm(itx,ip,itm)=icount_fore_tm(itx,ip,itm)+1
- iiout = ibest_save_tm(itx,ip,itm)
- rusage(iiout)=101.1_r_kind
- rusage(iobs)=usage
- ibest_save_tm(itx,ip,itm)=iobs
! Case: first obs at this location,
! --> keep this obs as starting point
- elseif (icount_fore_tm(itx,ip,itm)==0) then
+ elseif (.not. icount_fore_tm(itx,ip,itm)) then
iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=usage
score_crit_fore_tm(itx,ip,itm)= crit
- ibest_obs_tm(itx,ip,itm) = iobs
- icount_fore_tm(itx,ip,itm)=icount_fore_tm(itx,ip,itm)+1
- ibest_save_tm(itx,ip,itm) = iobs
+ ibest_obs_fore_tm(itx,ip,itm) = iobs
+ icount_fore_tm(itx,ip,itm)=.true.
! Case: none of the above cases are satisified,
-! --> don't use this obs
+! Case: obs score > best value at this location,
+! --> do not use this obs, return to calling program.
else
- iuse = .false.
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.0_r_kind
+ if(save_all)then
+ iobs=iobs+1
+ rthin(iobs)=.true.
+ else
+ iuse=.false.
+ end if
end if
! TDR aft (Pseudo-dual-Doppler-radars)
else if(aftswp) then ! fore sweeps
-! Case: obs score > best value at this location,
-! --> do not use this obs, return to calling program.
- if(crit > score_crit_aft_tm(itx,ip,itm) .and. icount_aft_tm(itx,ip,itm) > 0) then
- iuse=.false.
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.0_r_kind
+ if(.not.setaft)call createaft_tm
! Case: obs score < best value at this location,
! --> update score, count, and best obs counters
- elseif (icount_aft_tm(itx,ip,itm) > 0 .and. crit < score_crit_aft_tm(itx,ip,itm)) then
+ if (icount_aft_tm(itx,ip,itm) .and. crit < score_crit_aft_tm(itx,ip,itm)) then
iobs=iobs+1
- iobsout=iobs
+ itmp=ibest_obs_aft_tm(itx,ip,itm)
+ rthin(itmp)=.true.
score_crit_aft_tm(itx,ip,itm)= crit
-! iobsout=ibest_obs_tm(itx,ip)
- icount_aft_tm(itx,ip,itm)=icount_aft_tm(itx,ip,itm)+1
- iiout = ibest_save_tm(itx,ip,itm)
- rusage(iiout)=101.0_r_kind
- rusage(iobs)=usage
- ibest_save_tm(itx,ip,itm)=iobs
+ ibest_obs_aft_tm(itx,ip,itm)=iobs
! Case: first obs at this location,
! --> keep this obs as starting point
- elseif (icount_aft_tm(itx,ip,itm)==0) then
+ elseif (.not. icount_aft_tm(itx,ip,itm)) then
iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=usage
score_crit_aft_tm(itx,ip,itm)= crit
- ibest_obs_tm(itx,ip,itm) = iobs
- icount_aft_tm(itx,ip,itm)=icount_aft_tm(itx,ip,itm)+1
- ibest_save_tm(itx,ip,itm) = iobs
+ ibest_obs_aft_tm(itx,ip,itm) = iobs
+ icount_aft_tm(itx,ip,itm)=.true.
+! Case: obs score > best value at this location,
! Case: none of the above cases are satisified,
-! --> don't use this obs
+! --> do not use this obs, return to calling program.
else
- iuse = .false.
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.1_r_kind
+ if(save_all)then
+ iobs=iobs+1
+ rthin(iobs)=.true.
+ else
+ iuse=.false.
+ end if
end if
else
-! Case: obs score > best value at this location,
-! --> do not use this obs, return to calling program.
- if(crit > score_crit_tm(itx,ip,itm) .and. icount_tm(itx,ip,itm) > 0) then
- iuse=.false.
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.0_r_kind
+ if(.not.setnormal)call createnormal_tm
! Case: obs score < best value at this location,
! --> update score, count, and best obs counters
- elseif (icount_tm(itx,ip,itm) > 0 .and. crit < score_crit_tm(itx,ip,itm)) then
+ if (icount_tm(itx,ip,itm) .and. crit < score_crit_tm(itx,ip,itm)) then
iobs=iobs+1
- iobsout=iobs
+ itmp=ibest_obs_tm(itx,ip,itm)
+ rthin(itmp)=.true.
score_crit_tm(itx,ip,itm)= crit
- icount_tm(itx,ip,itm)=icount_tm(itx,ip,itm)+1
- iiout = ibest_obs_tm(itx,ip,itm)
- rusage(iiout)=101.0_r_kind
- rusage(iobs)=usage
- ibest_save_tm(itx,ip,itm)=iin
- ibest_obs_tm(itx,ip,itm)=iobs
+ ibest_obs_tm(itx,ip,itm) = iobs
! Case: first obs at this location,
! --> keep this obs as starting point
- elseif (icount_tm(itx,ip,itm)==0) then
+ elseif (.not. icount_tm(itx,ip,itm)) then
+
iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=usage
+ icount_tm(itx,ip,itm)=.true.
score_crit_tm(itx,ip,itm)= crit
- ibest_obs_tm(itx,ip,itm) = iobs
- icount_tm(itx,ip,itm)=icount_tm(itx,ip,itm)+1
- ibest_save_tm(itx,ip,itm) = iin
-
+ ibest_obs_tm(itx,ip,itm)=iobs
+! Case: obs score > best value at this location,
! Case: none of the above cases are satisified,
-! --> don't use this obs
+! --> do not use this obs, return to calling program.
else
- iuse = .false.
- iobs=iobs+1
- iobsout=iobs
- rusage(iobs)=101.0_r_kind
+ if(save_all)then
+ iobs=iobs+1
+ rthin(iobs)=.true.
+ else
+ iuse=.false.
+ end if
end if
end if
@@ -663,14 +496,24 @@ subroutine del3grids_tm
if (.not.use_all_tm) then
deallocate(mlon,glat,glon,hll)
- deallocate(icount_tm)
- deallocate(icount_fore_tm)
- deallocate(icount_aft_tm)
- deallocate(ibest_obs_tm)
- deallocate(ibest_save_tm)
- deallocate(score_crit_tm)
- deallocate(score_crit_fore_tm)
- deallocate(score_crit_aft_tm)
+ if(setnormal)then
+ deallocate(icount_tm)
+ deallocate(ibest_obs_tm)
+ deallocate(score_crit_tm)
+ setnormal=.false.
+ end if
+ if(setfore)then
+ deallocate(icount_fore_tm)
+ deallocate(ibest_obs_fore_tm)
+ deallocate(score_crit_fore_tm)
+ setfore=.false.
+ end if
+ if(setaft)then
+ deallocate(icount_aft_tm)
+ deallocate(ibest_obs_aft_tm)
+ deallocate(score_crit_aft_tm)
+ setaft=.false.
+ end if
endif
end subroutine del3grids_tm
diff --git a/src/gsi/correlated_obsmod.F90 b/src/gsi/correlated_obsmod.F90
index 683e13d742..17cd94efe1 100644
--- a/src/gsi/correlated_obsmod.F90
+++ b/src/gsi/correlated_obsmod.F90
@@ -961,14 +961,18 @@ subroutine upd_varch_
enddo
nchanl1=jc
- if(nchanl1==0) call die(myname_,' improperly set GSI_BundleErrorCov')
if(.not.amiset_(GSI_BundleErrorCov(itbl))) then
- if (iamroot_) write(6,*) 'WARNING: Error Covariance not set for ',trim(idnames(itbl))
+ if (iamroot_) write(6,*) trim(myname_), ' WARNING: Error Covariance not set for ',trim(idnames(itbl))
cycle read_tab
endif
nch_active=GSI_BundleErrorCov(itbl)%nch_active
- if(nch_active<0) return
+ if(nch_active<0) then
+ if (iamroot_) write(6,*) trim(myname_), ' WARNING: No active channels for ',trim(idnames(itbl))
+ return
+ endif
+
+ if(nchanl1==0) call die(myname_,' improperly set GSI_BundleErrorCov')
if(GMAO_ObsErrorCov)then
do jj=1,nch_active
@@ -977,11 +981,15 @@ subroutine upd_varch_
if(isurf==1) then
if(iamroot_)write(6,'(1x,a6,a20,2i6,2f20.15)')'>>>',idnames(itbl),jj,nn,varch(mm),sqrt(GSI_BundleErrorCov(itbl)%R(jj,jj))
varch_sea(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(jj,jj))
- endif
- if(isurf==2) varch_land(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(jj,jj))
- if(isurf==3) varch_ice(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(jj,jj))
- if(isurf==4) varch_snow(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(jj,jj))
- if(isurf==5) varch_mixed(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(jj,jj))
+ else if(isurf==2) then
+ varch_land(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(jj,jj))
+ else if(isurf==3) then
+ varch_ice(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(jj,jj))
+ else if(isurf==4) then
+ varch_snow(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(jj,jj))
+ else if(isurf==5) then
+ varch_mixed(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(jj,jj))
+ end if
enddo
else
allocate(ircv(nchanl1))
@@ -1023,15 +1031,9 @@ subroutine upd_varch_
IJsubset(iii)=ijac(ii) ! subset indexes in channels presently in use
endif
enddo
- if (iii/=ncp) then
+ if (iii/=ncp .or. jjj/=ncp) then
if (iamroot_) then
- write(6,*) myname, ' iii,ncp= ',iii,ncp
- endif
- call die(myname_,' serious dimensions insconsistency, aborting')
- endif
- if (jjj/=ncp) then
- if (iamroot_) then
- write(6,*) myname, ' jjj,ncp= ',jjj,ncp
+ write(6,*) myname, ' iii,jjj,ncp= ',iii,jjj,ncp
endif
call die(myname_,' serious dimensions insconsistency, aborting')
endif
@@ -1039,11 +1041,17 @@ subroutine upd_varch_
nn=IJsubset(ii)
mm=ich1(nn)
rr=IRsubset(ii)
- if(isurf==1) varch_sea(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(rr,rr))
- if(isurf==2) varch_land(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(rr,rr))
- if(isurf==3) varch_ice(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(rr,rr))
- if(isurf==4) varch_snow(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(rr,rr))
- if(isurf==5) varch_mixed(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(rr,rr))
+ if(isurf==1) then
+ varch_sea(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(rr,rr))
+ else if(isurf==2) then
+ varch_land(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(rr,rr))
+ else if(isurf==3) then
+ varch_ice(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(rr,rr))
+ else if(isurf==4) then
+ varch_snow(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(rr,rr))
+ else if(isurf==5) then
+ varch_mixed(mm)=sqrt(GSI_BundleErrorCov(itbl)%R(rr,rr))
+ end if
enddo
! clean up
deallocate(IJsubset)
@@ -1260,18 +1268,12 @@ logical function scale_jac_(depart,obs,err2,raterr2,jacobian,nchanl,varinv,diaga
IJsubset(iii)=ijac(ii) ! subset indexes in Jac/dep presently in use
endif
enddo
- if (iii/=ncp) then
+ if (iii/=ncp .and. jjj/=ncp) then
if (iamroot_) then
- write(6,*) myname, ' iii,ncp= ',iii,ncp
+ write(6,*) myname, ' iii,ncp= ',iii,jjj,ncp
endif
call die(myname_,' serious dimensions insconsistency (R), aborting')
endif
- if (jjj/=ncp) then
- if (iamroot_) then
- write(6,*) myname, ' jjj,ncp= ',jjj,ncp
- endif
- call die(myname_,' serious dimensions insconsistency (J), aborting')
- endif
if( ErrorCov%method<0 ) then
! Keep departures and Jacobian unchanged
@@ -1300,33 +1302,25 @@ logical function scale_jac_(depart,obs,err2,raterr2,jacobian,nchanl,varinv,diaga
! decompose the sub-matrix - returning the result in the
! structure holding the full covariance
- nsigjac=size(jacobian,1)
- allocate(row(nsigjac,ncp))
- allocate(col(ncp),col2(ncp))
- row=zero_quad
- col=zero_quad
- col2=zero_quad
-
- allocate(qcaj(ncp))
allocate(UT(ncp,ncp))
- qcaj = one
- UT = zero
if( ErrorCov%method==2 ) then
if(lqcoef)then
+ allocate(qcaj(ncp))
do jj=1,ncp
- jjj=IJsubset(jj)
- qcaj(jj) = raterr2(jjj)
+ qcaj(jj) = raterr2(IJsubset(jj))
enddo
subset = choleskydecom_inv_ (IRsubset,IJsubset,ErrorCov,UT,diagadd,qcaj)
+ deallocate(qcaj)
else
subset = choleskydecom_inv_ (IRsubset,IJsubset,ErrorCov,UT,diagadd)
endif
else if( ErrorCov%method==1 ) then
+ allocate(qcaj(ncp))
do jj=1,ncp
- jjj=IJsubset(jj)
- qcaj(jj) = varinv(jjj)
+ qcaj(jj) = varinv(IJsubset(jj))
enddo
subset = choleskydecom_inv_ (IRsubset,IJsubset,ErrorCov,UT,diagadd,qcaj)
+ deallocate(qcaj)
endif
if(.not.subset) then
@@ -1345,23 +1339,31 @@ logical function scale_jac_(depart,obs,err2,raterr2,jacobian,nchanl,varinv,diaga
do kk=ii,ncp
rinvdiag(ii)=rinvdiag(ii)+UT(ii,kk)**2
enddo
- enddo
+ end do
+ nsigjac=size(jacobian,1)
+ allocate(row(nsigjac,ncp))
+ allocate(col(ncp),col2(ncp))
+!$omp parallel do schedule(dynamic,1) private(ii,jj,nn)
do ii=1,ncp
+ row(:,ii)=zero_quad
+ col(ii)=zero_quad
+ col2(ii)=zero_quad
do jj=1,ii
nn=IJsubset(jj)
col(ii) = col(ii) + UT(jj,ii) * depart(nn)
- col2(ii) = col2(ii) + UT(jj,ii) * obs(nn)
+ col2(ii) = col2(ii) + UT(jj,ii) * obs(nn)
row(:,ii) = row(:,ii) + UT(jj,ii) * jacobian(:,nn)
enddo
enddo
+ deallocate(UT)
! Place Jacobian and departure in output arrays
- do jj=1,ncp
- mm=IJsubset(jj)
- depart(mm)=col(jj)
- obs(mm)=col2(jj)
- jacobian(:,mm)=row(:,jj)
+ do ii=1,ncp
+ mm=IJsubset(ii)
+ depart(mm)=col(ii)
+ obs(mm)=col2(ii)
+ jacobian(:,mm)=row(:,ii)
raterr2(mm) = one
err2(mm) = one
wgtjo(mm) = one
@@ -1369,8 +1371,6 @@ logical function scale_jac_(depart,obs,err2,raterr2,jacobian,nchanl,varinv,diaga
deallocate(col,col2)
deallocate(row)
- deallocate(qcaj)
- deallocate(UT)
else if( ErrorCov%method==3 ) then !use diag(Re) scales GSI specified errors
! inv(Rg) = inv(De*Dg)
@@ -1445,17 +1445,16 @@ logical function choleskydecom_inv_(Isubset,IJsubset,ErrorCov,UT,diagadd,qcaj)
do ii=1,ncp
UT(ii,jj) = ErrorCov%R(Isubset(ii),Isubset(jj))/sqrt(qcaj(ii)*qcaj(jj))
enddo
+ UT(jj,jj) = UT(jj,jj)+diagadd(IJsubset(jj))
enddo
else
do jj=1,ncp
do ii=1,ncp
UT(ii,jj) = ErrorCov%R(Isubset(ii),Isubset(jj))
enddo
+ UT(jj,jj) = UT(jj,jj)+diagadd(IJsubset(jj))
enddo
endif
- do jj=1,ncp
- UT(jj,jj) = UT(jj,jj)+diagadd(IJsubset(jj))
- enddo
if(r_kind==r_single) then ! this trick only works because this uses the f77 lapack interfaces
call SPOTRF('U', ncp, UT, ncp, info )
else if(r_kind==r_double) then
diff --git a/src/gsi/cplr_get_fv3_regional_ensperts.f90 b/src/gsi/cplr_get_fv3_regional_ensperts.f90
index f99ca39790..9b841f012c 100644
--- a/src/gsi/cplr_get_fv3_regional_ensperts.f90
+++ b/src/gsi/cplr_get_fv3_regional_ensperts.f90
@@ -1,5 +1,5 @@
module get_fv3_regional_ensperts_mod
-use abstract_get_fv3_regional_ensperts_mod,only: abstract_get_fv3_regional_ensperts_class
+ use abstract_get_fv3_regional_ensperts_mod,only: abstract_get_fv3_regional_ensperts_class
use kinds, only : i_kind
use general_sub2grid_mod, only: sub2grid_info
use constants, only:max_varname_length
@@ -8,14 +8,18 @@ module get_fv3_regional_ensperts_mod
procedure, pass(this) :: get_fv3_regional_ensperts => get_fv3_regional_ensperts_run
procedure, pass(this) :: ens_spread_dualres_regional => ens_spread_dualres_regional_fv3_regional
procedure, pass(this) :: general_read_fv3_regional
+ procedure, pass(this) :: general_read_fv3_regional_parallel_over_ens
+ procedure, pass(this) :: parallel_read_fv3_step2
+ procedure, nopass :: fill_regional_2d
end type get_fv3_regional_ensperts_class
- type(sub2grid_info):: grd_fv3lam_ens_dynvar_io_nouv,grd_fv3lam_ens_tracer_io_nouv,grd_fv3lam_ens_uv
+ type(sub2grid_info):: grd_fv3lam_ens_dynvar_io_nouv,grd_fv3lam_ens_tracer_io_nouv,grd_fv3lam_ens_uv,grd_fv3lam_ens_phyvar_io_nouv
character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_ens_io_dynmetvars3d_nouv
! copy of cvars3d excluding uv 3-d fields
character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_ens_io_tracermetvars3d_nouv
! copy of cvars3d excluding uv 3-d fields
character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_ens_io_dynmetvars2d_nouv
character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_ens_io_tracermetvars2d_nouv
+ character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_ens_io_phymetvars3d_nouv
contains
subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
@@ -34,6 +38,7 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
!
! 2021-08-10 lei - modify for fv3-lam ensemble spread output
! 2021-11-01 lei - modify for fv3-lam parallel IO
+ ! 2022-03-01 X.Lu & X.Wang - modify for hafs dual ens. POC: xuguang.wang@ou.edu
! input argument list:
!
! output argument list:
@@ -46,9 +51,9 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
use kinds, only: r_kind,i_kind,r_single
use constants, only: zero,one,half,zero_single,rd_over_cp,one_tenth
- use mpimod, only: mpi_comm_world,ierror,mype
- use hybrid_ensemble_parameters, only: n_ens,grd_ens
- use hybrid_ensemble_parameters, only: l_both_fv3sar_gfs_ens, n_ens_gfs,n_ens_fv3sar
+ use mpimod, only: mpi_comm_world,ierror,mype,npe
+ use hybrid_ensemble_parameters, only: n_ens,grd_ens,parallelization_over_ensmembers
+ use hybrid_ensemble_parameters, only: l_both_fv3sar_gfs_ens,n_ens_gfs,n_ens_fv3sar,weight_ens_fv3sar
use hybrid_ensemble_parameters, only: ntlevs_ens,ensemble_path
use control_vectors, only: cvars2d,cvars3d,nc2d,nc3d
use gsi_bundlemod, only: gsi_bundlecreate
@@ -69,6 +74,8 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
use gsi_rfv3io_mod, only: fv3lam_io_dynmetvars2d_nouv,fv3lam_io_tracermetvars2d_nouv
use netcdf , only: nf90_open, nf90_close,nf90_nowrite,nf90_inquire,nf90_format_netcdf4
use netcdf_mod , only: nc_check
+ use gsi_rfv3io_mod, only: fv3lam_io_phymetvars3d_nouv
+ use obsmod, only: if_model_dbz,if_model_fed
implicit none
@@ -79,7 +86,11 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,grd_ens%nsig):: u,v,tv,oz,rh
real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2):: ps
- real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,grd_ens%nsig)::w,ql,qi,qr,qg,qs,qnr
+ real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,grd_ens%nsig)::w,ql,qi,qr,qg,qs,qnr,dbz,fed
+ real(r_kind),dimension(:,:,:),allocatable :: gg_u,gg_v,gg_tv,gg_rh
+ real(r_kind),dimension(:,:,:),allocatable :: gg_w,gg_dbz,gg_qr,gg_qs, &
+ gg_qi,gg_qg,gg_oz,gg_cwmr,gg_fed
+ real(r_kind),dimension(:,:),allocatable :: gg_ps
real(r_single),pointer,dimension(:,:,:):: w3 =>NULL()
real(r_single),pointer,dimension(:,:):: w2 =>NULL()
@@ -96,9 +107,9 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
integer(i_kind):: i,j,k,n,mm1,istatus
integer(i_kind):: ndynvario2d,ntracerio2d
- integer(r_kind):: ndynvario3d,ntracerio3d
+ integer(r_kind):: ndynvario3d,ntracerio3d,nphyvario3d
integer(i_kind):: inner_vars,numfields
- integer(i_kind):: ilev,ic2,ic3
+ integer(i_kind):: ilev,ic2,ic3,iope
integer(i_kind):: m
integer(i_kind)::loc_id,ncfmt
@@ -107,6 +118,8 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
type(type_fv3regfilenameg)::fv3_filename
integer(i_kind):: imem_start,n_fv3sar
+ integer(i_kind):: i_caseflag
+
if(n_ens/=(n_ens_gfs+n_ens_fv3sar)) then
write(6,*)'wrong, the sum of n_ens_gfs and n_ens_fv3sar not equal n_ens, stop'
write(6,*)"n_ens, n_ens_gfs and n_ens_fv3sar are",n_ens, n_ens_gfs , n_ens_fv3sar
@@ -125,8 +138,10 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
!clt setup varnames for IO
ndynvario2d=0
ntracerio2d=0
+ nphyvario3d=0
ndynvario3d=size(fv3lam_io_dynmetvars3d_nouv)
ntracerio3d=size(fv3lam_io_tracermetvars3d_nouv)
+ nphyvario3d=size(fv3lam_io_phymetvars3d_nouv)
if (allocated(fv3lam_io_dynmetvars2d_nouv))then
ndynvario2d=size(fv3lam_io_dynmetvars2d_nouv)
endif
@@ -137,6 +152,10 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
allocate(fv3lam_ens_io_tracermetvars3d_nouv(ndynvario3d))
fv3lam_ens_io_dynmetvars3d_nouv=fv3lam_io_dynmetvars3d_nouv
fv3lam_ens_io_tracermetvars3d_nouv=fv3lam_io_tracermetvars3d_nouv
+ if ( nphyvario3d > 0 )then
+ allocate(fv3lam_ens_io_phymetvars3d_nouv(nphyvario3d))
+ fv3lam_ens_io_phymetvars3d_nouv=fv3lam_io_phymetvars3d_nouv
+ end if
if (ndynvario2d > 0 ) then
allocate(fv3lam_ens_io_dynmetvars2d_nouv(ndynvario2d))
fv3lam_ens_io_dynmetvars2d_nouv=fv3lam_io_dynmetvars2d_nouv
@@ -168,6 +187,24 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
call general_sub2grid_create_info(grd_fv3lam_ens_dynvar_io_nouv,inner_vars,grd_ens%nlat,&
grd_ens%nlon,grd_ens%nsig,numfields,regional,names=names,lnames=lnames)
+ if( nphyvario3d > 0 )then
+ inner_vars=1
+ numfields=inner_vars*(nphyvario3d*grd_ens%nsig)
+ deallocate(lnames,names)
+ allocate(lnames(1,numfields),names(1,numfields))
+ ilev=1
+ do i=1,nphyvario3d
+ do k=1,grd_ens%nsig
+ lnames(1,ilev)=k
+ names(1,ilev)=fv3lam_ens_io_phymetvars3d_nouv(i)
+ ilev=ilev+1
+ enddo
+ enddo
+
+ call general_sub2grid_create_info(grd_fv3lam_ens_phyvar_io_nouv,inner_vars,grd_ens%nlat,&
+ grd_ens%nlon,grd_ens%nsig,numfields,regional,names=names,lnames=lnames)
+ end if
+
inner_vars=1
numfields=inner_vars*(ntracerio3d*grd_ens%nsig+ntracerio2d)
deallocate(lnames,names)
@@ -254,16 +291,87 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
mm1=mype+1
kap1=rd_over_cp+one
kapr=one/rd_over_cp
+
+ if( parallelization_over_ensmembers ) then
+ if(n_ens_fv3sar>npe) then
+ parallelization_over_ensmembers=.false.
+130 format('Disabling parallelization_over_ensmembers because number of ensemble members (',I0,') is greater than number of MPI ranks (',I0,').')
+ if(mype==0) then
+ write(6,130) n_ens_fv3sar,npe
+ endif
+ endif
+ endif ! parallelization_over_ensmembers
+
+ if(parallelization_over_ensmembers .and. mype==0) then
+ write(6,'(I0,A)') mype,': will read ensemble data in parallel (parallelization_over_ensmembers=.true.)'
+ endif
+
+ if( parallelization_over_ensmembers )then
+ do n=1,n_ens_fv3sar
+ write(ensfilenam_str,22) trim(adjustl(ensemble_path)),ens_fhrlevs(m),n
+22 format(a,'fv3SAR',i2.2,'_ens_mem',i3.3)
+ iope=(n-1)*npe/n_ens_fv3sar
+ ! DEFINE INPUT FILE NAME
+ fv3_filename%grid_spec=trim(ensfilenam_str)//'-fv3_grid_spec'
+ fv3_filename%ak_bk=trim(ensfilenam_str)//'-fv3_akbk'
+ fv3_filename%dynvars=trim(ensfilenam_str)//'-fv3_dynvars'
+ fv3_filename%tracers=trim(ensfilenam_str)//"-fv3_tracer"
+ fv3_filename%phyvars=trim(ensfilenam_str)//'-fv3_phyvars'
+ fv3_filename%sfcdata=trim(ensfilenam_str)//"-fv3_sfcdata"
+ fv3_filename%couplerres=trim(ensfilenam_str)//"-coupler.res"
+
+ if( mype==iope) then
+ allocate(gg_u(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ allocate(gg_v(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ allocate(gg_tv(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ allocate(gg_rh(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ allocate(gg_oz(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ allocate(gg_ps(grd_ens%nlat,grd_ens%nlon))
+
+ if ( if_model_dbz .or. if_model_fed ) then
+ allocate(gg_w(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ allocate(gg_qr(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ allocate(gg_qs(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ allocate(gg_qi(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ allocate(gg_qg(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ allocate(gg_cwmr(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ end if
+ if ( if_model_dbz) then
+ allocate(gg_dbz(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ end if
+ if ( if_model_fed) then
+ allocate(gg_fed(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig))
+ end if
+
+ if ( if_model_dbz .and. if_model_fed) then
+ call this%general_read_fv3_regional_parallel_over_ens(iope,fv3_filename,gg_ps,gg_u,gg_v,gg_tv,gg_rh,gg_oz,&
+ g_ql=gg_cwmr,g_qi=gg_qi,g_qr=gg_qr,g_qs=gg_qs,g_qg=gg_qg,g_w=gg_w,g_dbz=gg_dbz,g_fed=gg_fed)
+ elseif ( if_model_dbz ) then
+ call this%general_read_fv3_regional_parallel_over_ens(iope,fv3_filename,gg_ps,gg_u,gg_v,gg_tv,gg_rh,gg_oz,&
+ g_ql=gg_cwmr,g_qi=gg_qi,g_qr=gg_qr,g_qs=gg_qs,g_qg=gg_qg,g_w=gg_w,g_dbz=gg_dbz)
+ elseif ( if_model_fed ) then
+ call this%general_read_fv3_regional_parallel_over_ens(iope,fv3_filename,gg_ps,gg_u,gg_v,gg_tv,gg_rh,gg_oz,&
+ g_ql=gg_cwmr,g_qi=gg_qi,g_qr=gg_qr,g_qs=gg_qs,g_qg=gg_qg,g_w=gg_w,g_fed=gg_fed)
+ else
+ call this%general_read_fv3_regional_parallel_over_ens(iope,fv3_filename,gg_ps,gg_u,gg_v,gg_tv,gg_rh,gg_oz)
+ end if
+ end if !mype
+ end do
+ if(mype==0) then
+ write(6,'(I0,A)') mype,': reading ensemble data in parallel is done (parallelization_over_ensmembers=.true.)'
+ endif
+ end if
+ call MPI_Barrier(mpi_comm_world,ierror)
!
! LOOP OVER ENSEMBLE MEMBERS
do n_fv3sar=1,n_ens_fv3sar
n=n_ens_gfs+n_fv3sar
write(ensfilenam_str,22) trim(adjustl(ensemble_path)),ens_fhrlevs(m),n_fv3sar
-22 format(a,'fv3SAR',i2.2,'_ens_mem',i3.3)
! DEFINE INPUT FILE NAME
fv3_filename%grid_spec=trim(ensfilenam_str)//'-fv3_grid_spec' !exmaple thinktobe
fv3_filename%ak_bk=trim(ensfilenam_str)//'-fv3_akbk'
fv3_filename%dynvars=trim(ensfilenam_str)//'-fv3_dynvars'
+ fv3_filename%phyvars=trim(ensfilenam_str)//'-fv3_phyvars'
fv3_filename%tracers=trim(ensfilenam_str)//"-fv3_tracer"
fv3_filename%sfcdata=trim(ensfilenam_str)//"-fv3_sfcdata"
fv3_filename%couplerres=trim(ensfilenam_str)//"-coupler.res"
@@ -299,15 +407,134 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
endif
!
! READ ENEMBLE MEMBERS DATA
- if (mype == 0) write(6,'(a,a)') &
- 'CALL READ_FV3_REGIONAL_ENSPERTS FOR ENS DATA with the filename str : ',trim(ensfilenam_str)
- if (.not.l_use_dbz_directDA ) then ! Read additional hydrometers and w for dirZDA
- call this%general_read_fv3_regional(fv3_filename,ps,u,v,tv,rh,oz)
- else
- call this%general_read_fv3_regional(fv3_filename,ps,u,v,tv,rh,oz, &
- g_ql=ql,g_qi=qi,g_qr=qr,g_qs=qs,g_qg=qg,g_qnr=qnr,g_w=w)
+ !
+ ! There are three options to control the list of variables that
+ ! will be read in along with the basic variables, ps,u,v,tv,rh,oz.
+
+ ! parallelization_over_ensmembers=.True. only works for cases when l_use_dbz_directDA=.False.
+ ! Noted that l_use_dbz_directDA and if_modle_dbz couldn't be true at the same time
+
+ !
+ ! I_CASEFLAG defination
+ !
+
+ ! default: all the three options ( l_use_dbz_directDA, if_model_dbz, if_model_fed) are turned off .i.e.,
+ ! if(.not. (l_use_dbz_directDA .or. if_model_dbz .or. if_model_fed ))
+ ! read in ps,u,v,tv,rh,oz
+ i_caseflag=0
+
+ ! only l_use_dbz_directDA is true
+ if (l_use_dbz_directDA .and. .not.if_model_dbz .and. .not.if_model_fed) i_caseflag=1
+
+ ! only if_model_dbz is true
+ if(.not.l_use_dbz_directDA .and. if_model_dbz .and. .not.if_model_fed) i_caseflag=2
+
+ ! only if_model_fed is true
+ if(.not.l_use_dbz_directDA .and. .not.if_model_dbz .and. if_model_fed) i_caseflag=3
+
+ ! l_use_dbz_directDA=.true. and if_model_fed=.true.
+ if(l_use_dbz_directDA .and. .not.if_model_dbz .and. if_model_fed) i_caseflag=4
+
+ ! if_model_dbz=.true. and if_model_fed=.true.
+ if(.not. l_use_dbz_directDA.and. if_model_dbz .and. if_model_fed) i_caseflag=5
+
+
+ !--------------------------------------------------
+ ! When .not. parallelization_over_ensmembers=.True.
+ ! All the above 6 cases (i_caseflag=0,1,2,3,4,5) are valid in
+ ! the current applications as of Oct 20 2023.
+
+ !--------------------------------------------
+ ! When parallelization_over_ensmembers=.True.
+ ! Only i_flagcase=0,2,3,5 are vaild choices.
+
+
+ if( .not. parallelization_over_ensmembers )then
+ if (mype == 0) write(6,'(a,a)') &
+ 'CALL READ_FV3_REGIONAL_ENSPERTS FOR ENS DATA with the filename str : ',trim(ensfilenam_str)
+
+ select case (i_caseflag)
+ case (0)
+ call this%general_read_fv3_regional(fv3_filename,ps,u,v,tv,rh,oz)
+ case (1)
+ call this%general_read_fv3_regional(fv3_filename,ps,u,v,tv,rh,oz, &
+ g_ql=ql,g_qi=qi,g_qr=qr,g_qs=qs,g_qg=qg,g_qnr=qnr,g_w=w)
+ case (2)
+ call this%general_read_fv3_regional(fv3_filename,ps,u,v,tv,rh,oz, &
+ g_ql=ql,g_qi=qi,g_qr=qr,g_qs=qs,g_qg=qg,g_qnr=qnr,g_w=w,g_dbz=dbz)
+ case (3)
+ call this%general_read_fv3_regional(fv3_filename,ps,u,v,tv,rh,oz, &
+ g_ql=ql,g_qi=qi,g_qr=qr,g_qs=qs,g_qg=qg,g_w=w,g_fed=fed)
+ case (4)
+ call this%general_read_fv3_regional(fv3_filename,ps,u,v,tv,rh,oz, &
+ g_ql=ql,g_qi=qi,g_qr=qr,g_qs=qs,g_qg=qg,g_qnr=qnr,g_w=w,g_fed=fed)
+ case (5)
+ call this%general_read_fv3_regional(fv3_filename,ps,u,v,tv,rh,oz, &
+ g_ql=ql,g_qi=qi,g_qr=qr,g_qs=qs,g_qg=qg,g_qnr=qnr,g_w=w,g_dbz=dbz,g_fed=fed)
+ end select
end if
-
+
+ if( parallelization_over_ensmembers )then
+ iope=(n_fv3sar-1)*npe/n_ens_fv3sar
+ if(mype==iope) then
+ write(0,'(I0,A,I0,A)') mype,': scatter member ',n_fv3sar,' to other ranks...'
+ select case (i_caseflag)
+ case (0)
+ call this%parallel_read_fv3_step2(mype,iope,&
+ g_ps=ps,g_u=u,g_v=v,g_tv=tv,g_rh=rh,g_ql=ql,g_oz=oz, &
+ gg_ps=gg_ps,gg_tv=gg_tv,gg_u=gg_u,gg_v=gg_v,gg_rh=gg_rh)
+ case (2)
+ call this%parallel_read_fv3_step2(mype,iope,&
+ g_ps=ps,g_u=u,g_v=v,g_tv=tv,g_rh=rh,g_ql=ql,&
+ g_oz=oz,g_w=w,g_qr=qr,g_qs=qs,g_qi=qi,g_qg=qg,g_dbz=dbz,&
+ gg_ps=gg_ps,gg_tv=gg_tv,gg_u=gg_u,gg_v=gg_v,&
+ gg_rh=gg_rh,gg_w=gg_w,gg_dbz=gg_dbz,gg_qr=gg_qr,&
+ gg_qs=gg_qs,gg_qi=gg_qi,gg_qg=gg_qg,gg_ql=gg_cwmr)
+ case (3)
+ call this%parallel_read_fv3_step2(mype,iope,&
+ g_ps=ps,g_u=u,g_v=v,g_tv=tv,g_rh=rh,g_ql=ql,&
+ g_oz=oz,g_w=w,g_qr=qr,g_qs=qs,g_qi=qi,g_qg=qg,g_fed=fed,&
+ gg_ps=gg_ps,gg_tv=gg_tv,gg_u=gg_u,gg_v=gg_v,&
+ gg_rh=gg_rh,gg_w=gg_w,gg_fed=gg_fed,gg_qr=gg_qr,&
+ gg_qs=gg_qs,gg_qi=gg_qi,gg_qg=gg_qg,gg_ql=gg_cwmr)
+ case (5)
+ call this%parallel_read_fv3_step2(mype,iope,&
+ g_ps=ps,g_u=u,g_v=v,g_tv=tv,g_rh=rh,g_ql=ql,&
+ g_oz=oz,g_w=w,g_qr=qr,g_qs=qs,g_qi=qi,g_qg=qg,g_dbz=dbz,g_fed=fed,&
+ gg_ps=gg_ps,gg_tv=gg_tv,gg_u=gg_u,gg_v=gg_v,&
+ gg_rh=gg_rh,gg_w=gg_w,gg_dbz=gg_dbz,gg_fed=gg_fed,gg_qr=gg_qr,&
+ gg_qs=gg_qs,gg_qi=gg_qi,gg_qg=gg_qg,gg_ql=gg_cwmr)
+ case (1,4)
+ write(6,*)'i_case_flag=1 or 4 is not a valid choice for parallelization_over_ensmembers=.T. Stop(8880) '
+ call stop2(8880)
+ end select
+ else
+ select case (i_caseflag)
+ case (0)
+ call this%parallel_read_fv3_step2(mype,iope,&
+ g_ps=ps,g_u=u,g_v=v,g_tv=tv,g_rh=rh,g_ql=ql,g_oz=oz)
+ case (2)
+ call this%parallel_read_fv3_step2(mype,iope,&
+ g_ps=ps,g_u=u,g_v=v,g_tv=tv,g_rh=rh,g_ql=ql,&
+ g_oz=oz,g_w=w,g_qr=qr,g_qs=qs,g_qi=qi,g_qg=qg,g_dbz=dbz)
+ case (3)
+ call this%parallel_read_fv3_step2(mype,iope,&
+ g_ps=ps,g_u=u,g_v=v,g_tv=tv,g_rh=rh,g_ql=ql,&
+ g_oz=oz,g_w=w,g_qr=qr,g_qs=qs,g_qi=qi,g_qg=qg,g_fed=fed)
+ case (5)
+ call this%parallel_read_fv3_step2(mype,iope,&
+ g_ps=ps,g_u=u,g_v=v,g_tv=tv,g_rh=rh,g_ql=ql,&
+ g_oz=oz,g_w=w,g_qr=qr,g_qs=qs,g_qi=qi,g_qg=qg,g_dbz=dbz,g_fed=fed)
+ case (1,4)
+ write(6,*)'i_case_flag=1 or 4 is not a valid choice for parallelization_over_ensmembers=.T. Stop(8880) '
+ call stop2(8880)
+ end select
+
+ endif
+
+ call MPI_Barrier(mpi_comm_world,ierror)
+ end if
+
! SAVE ENSEMBLE MEMBER DATA IN COLUMN VECTOR
do ic3=1,nc3d
@@ -463,6 +690,26 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
end do
end do
end do
+
+ case('dbz','DBZ')
+ do k=1,grd_ens%nsig
+ do i=1,grd_ens%lon2
+ do j=1,grd_ens%lat2
+ w3(j,i,k) = dbz(j,i,k)
+ x3(j,i,k)=x3(j,i,k)+dbz(j,i,k)
+ end do
+ end do
+ end do
+
+ case('fed','FED')
+ do k=1,grd_ens%nsig
+ do i=1,grd_ens%lon2
+ do j=1,grd_ens%lat2
+ w3(j,i,k) = fed(j,i,k)
+ x3(j,i,k)=x3(j,i,k)+fed(j,i,k)
+ end do
+ end do
+ end do
end select
@@ -508,7 +755,7 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
enddo
!
! CALCULATE ENSEMBLE MEAN
- bar_norm = one/float(n_ens_fv3sar)
+ bar_norm = one/real(n_ens_fv3sar,r_kind)
en_bar(m)%values=en_bar(m)%values*bar_norm
! Copy pbar to module array. ps_bar may be needed for vertical localization
@@ -536,7 +783,7 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
!
!
! CONVERT ENSEMBLE MEMBERS TO ENSEMBLE PERTURBATIONS
- sig_norm=sqrt(one/max(one,n_ens_fv3sar-one))
+ sig_norm=sqrt(weight_ens_fv3sar/max(one,n_ens_fv3sar-one))
do n=imem_start,n_ens
do i=1,nelen
@@ -546,7 +793,6 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
enddo ! it 4d loop
! CALCULATE ENSEMBLE SPREAD
- write_ens_sprd=.true.
if(write_ens_sprd ) then
call this%ens_spread_dualres_regional(mype,en_perts,nelen)
call mpi_barrier(mpi_comm_world,ierror) ! do we need this mpi_barrier here?
@@ -572,7 +818,7 @@ subroutine get_fv3_regional_ensperts_run(this,en_perts,nelen,ps_bar)
end subroutine get_fv3_regional_ensperts_run
subroutine general_read_fv3_regional(this,fv3_filenameginput,g_ps,g_u,g_v,g_tv,g_rh,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,g_qnr,g_w)
+ g_ql,g_qi,g_qr,g_qs,g_qg,g_qnr,g_w,g_dbz,g_fed)
!$$$ subprogram documentation block
! first compied from general_read_arw_regional . . . .
! subprogram: general_read_fv3_regional read fv3sar model ensemble members
@@ -603,7 +849,7 @@ subroutine general_read_fv3_regional(this,fv3_filenameginput,g_ps,g_u,g_v,g_tv,g
use gridmod, only: eta1_ll,eta2_ll
use constants, only: zero,one,fv,zero_single,one_tenth,h300
use hybrid_ensemble_parameters, only: grd_ens,q_hyb_ens
- use hybrid_ensemble_parameters, only: fv3sar_ensemble_opt
+ use hybrid_ensemble_parameters, only: fv3sar_ensemble_opt,dual_res
use mpimod, only: mpi_comm_world,mpi_rtype
use gsi_rfv3io_mod,only: type_fv3regfilenameg
@@ -623,7 +869,7 @@ subroutine general_read_fv3_regional(this,fv3_filenameginput,g_ps,g_u,g_v,g_tv,g
use hybrid_ensemble_parameters, only: grd_ens
use directDA_radaruse_mod, only: l_use_cvpqx, cvpqx_pval, cld_nt_updt
use directDA_radaruse_mod, only: l_cvpnr, cvpnr_pval
-
+ use obsmod, only:if_model_dbz,if_model_fed
implicit none
@@ -632,7 +878,7 @@ subroutine general_read_fv3_regional(this,fv3_filenameginput,g_ps,g_u,g_v,g_tv,g
class(get_fv3_regional_ensperts_class), intent(inout) :: this
type (type_fv3regfilenameg) , intent (in) :: fv3_filenameginput
real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,grd_ens%nsig),intent(out)::g_u,g_v,g_tv,g_rh,g_oz
- real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,grd_ens%nsig),optional,intent(out)::g_ql,g_qi,g_qr
+ real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,grd_ens%nsig),optional,intent(out)::g_ql,g_qi,g_qr,g_dbz,g_fed
real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,grd_ens%nsig),optional,intent(out)::g_qs,g_qg,g_qnr,g_w
real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2),intent(out):: g_ps
@@ -656,11 +902,13 @@ subroutine general_read_fv3_regional(this,fv3_filenameginput,g_ps,g_u,g_v,g_tv,g
character(len=24),parameter :: myname_ = 'general_read_fv3_regional'
type(gsi_bundle) :: gsibundle_fv3lam_ens_dynvar_nouv
type(gsi_bundle) :: gsibundle_fv3lam_ens_tracer_nouv
+ type(gsi_bundle) :: gsibundle_fv3lam_ens_phyvar_nouv
type(gsi_grid):: grid_ens
character(len=:),allocatable :: grid_spec !='fv3_grid_spec'
character(len=:),allocatable :: ak_bk !='fv3_akbk'
character(len=:),allocatable :: dynvars !='fv3_dynvars'
+ character(len=:),allocatable :: phyvars !='fv3_phyvars'
character(len=:),allocatable :: tracers !='fv3_tracer'
character(len=:),allocatable :: sfcdata !='fv3_sfcdata'
character(len=:),allocatable :: couplerres!='coupler.res'
@@ -676,6 +924,7 @@ subroutine general_read_fv3_regional(this,fv3_filenameginput,g_ps,g_u,g_v,g_tv,g
grid_spec=fv3_filenameginput%grid_spec
ak_bk=fv3_filenameginput%ak_bk
dynvars=fv3_filenameginput%dynvars
+ phyvars=fv3_filenameginput%phyvars
tracers=fv3_filenameginput%tracers
sfcdata=fv3_filenameginput%sfcdata
couplerres=fv3_filenameginput%couplerres
@@ -701,37 +950,49 @@ subroutine general_read_fv3_regional(this,fv3_filenameginput,g_ps,g_u,g_v,g_tv,g
endif
-
+ if(allocated(fv3lam_ens_io_phymetvars3d_nouv))then
+ call gsi_bundlecreate(gsibundle_fv3lam_ens_phyvar_nouv,grid_ens,'gsibundle_fv3lam_ens_phyvar_nouv',istatus, &
+ names3d=fv3lam_ens_io_phymetvars3d_nouv)
+ end if
if(fv3sar_ensemble_opt == 0 ) then
- call gsi_fv3ncdf_readuv(grd_fv3lam_ens_uv,g_u,g_v,fv3_filenameginput)
+ call gsi_fv3ncdf_readuv(grd_fv3lam_ens_uv,g_u,g_v,fv3_filenameginput,dual_res)
else
- call gsi_fv3ncdf_readuv_v1(grd_fv3lam_ens_uv,g_u,g_v,fv3_filenameginput)
+ call gsi_fv3ncdf_readuv_v1(grd_fv3lam_ens_uv,g_u,g_v,fv3_filenameginput,dual_res)
endif
if(fv3sar_ensemble_opt == 0) then
call gsi_fv3ncdf_read(grd_fv3lam_ens_dynvar_io_nouv,gsibundle_fv3lam_ens_dynvar_nouv,&
- fv3_filenameginput%dynvars,fv3_filenameginput)
+ fv3_filenameginput%dynvars,fv3_filenameginput,dual_res)
call gsi_fv3ncdf_read(grd_fv3lam_ens_tracer_io_nouv,gsibundle_fv3lam_ens_tracer_nouv,&
- fv3_filenameginput%tracers,fv3_filenameginput)
+ fv3_filenameginput%tracers,fv3_filenameginput,dual_res)
+ if( if_model_dbz .or. if_model_fed ) then
+ call gsi_fv3ncdf_read(grd_fv3lam_ens_phyvar_io_nouv,gsibundle_fv3lam_ens_phyvar_nouv,&
+ fv3_filenameginput%phyvars,fv3_filenameginput,dual_res)
+ end if
else
call gsi_fv3ncdf_read_v1(grd_fv3lam_ens_dynvar_io_nouv,gsibundle_fv3lam_ens_dynvar_nouv,&
- fv3_filenameginput%dynvars,fv3_filenameginput)
+ fv3_filenameginput%dynvars,fv3_filenameginput,dual_res)
call gsi_fv3ncdf_read_v1(grd_fv3lam_ens_tracer_io_nouv,gsibundle_fv3lam_ens_tracer_nouv,&
- fv3_filenameginput%tracers,fv3_filenameginput)
+ fv3_filenameginput%tracers,fv3_filenameginput,dual_res)
endif
ier=0
call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_dynvar_nouv, 'tsen' ,g_tsen ,istatus );ier=ier+istatus
- call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_tracer_nouv, 'q' ,g_q ,istatus );ier=ier+istatus
- call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_tracer_nouv, 'oz' ,g_oz ,istatus );ier=ier+istatus
- if (l_use_dbz_directDA) then
+ call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_tracer_nouv, 'q' ,g_q ,istatus );ier=ier+istatus
+ call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_tracer_nouv, 'oz' ,g_oz ,istatus );ier=ier+istatus
+ if (l_use_dbz_directDA .or. if_model_dbz .or. if_model_fed) then
call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_tracer_nouv, 'ql' ,g_ql ,istatus );ier=ier+istatus
call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_tracer_nouv, 'qi' ,g_qi ,istatus );ier=ier+istatus
call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_tracer_nouv, 'qr' ,g_qr ,istatus );ier=ier+istatus
call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_tracer_nouv, 'qs' ,g_qs ,istatus );ier=ier+istatus
call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_tracer_nouv, 'qg' ,g_qg ,istatus );ier=ier+istatus
+ if (l_use_dbz_directDA) &
call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_tracer_nouv, 'qnr',g_qnr ,istatus );ier=ier+istatus
call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_dynvar_nouv, 'w' , g_w ,istatus );ier=ier+istatus
+ if( if_model_dbz )&
+ call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_phyvar_nouv, 'dbz' , g_dbz ,istatus );ier=ier+istatus
+ if( if_model_fed )&
+ call GSI_Bundlegetvar ( gsibundle_fv3lam_ens_phyvar_nouv, 'fed' , g_fed, istatus );ier=ier+istatus
end if
@@ -834,11 +1095,349 @@ subroutine general_read_fv3_regional(this,fv3_filenameginput,g_ps,g_u,g_v,g_tv,g
enddo
call gsi_bundledestroy(gsibundle_fv3lam_ens_dynvar_nouv)
call gsi_bundledestroy(gsibundle_fv3lam_ens_tracer_nouv)
-
+ call gsi_bundledestroy(gsibundle_fv3lam_ens_phyvar_nouv)
return
end subroutine general_read_fv3_regional
+ subroutine general_read_fv3_regional_parallel_over_ens(this,iope,fv3_filenameginput,g_ps,g_u,g_v,g_tv,g_rh,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,g_qnr,g_w,g_dbz,g_fed)
+ !$$$ subprogram documentation block
+ ! first compied from general_read_arw_regional . . . .
+ ! subprogram: general_read_fv3_regional read fv3sar model ensemble members
+ ! prgmmr: Ting org: emc/ncep date: 2018
+ !
+ ! abstract: read ensemble members from the fv3sar model in "restart" or "cold start" netcdf format
+ ! for use with hybrid ensemble option.
+ !
+ ! program history log:
+ ! 2018- Ting - intial versions
+ ! 2022-04-01 Y. Wang and X. Wang - read all fields for each member for
+ ! parallel ensemble IO capability
+ ! poc: xuguang.wang@ou.edu
+ !
+ ! input argument list:
+ !
+ ! output argument list:
+ !
+ ! attributes:
+ ! language: f90
+ ! machine: ibm RS/6000 SP
+ !
+ !$$$ end documentation block
+
+ use netcdf, only: nf90_nowrite
+ use netcdf, only: nf90_open,nf90_close
+ use netcdf, only: nf90_inq_dimid,nf90_inquire_dimension
+ use netcdf, only: nf90_inq_varid,nf90_inquire_variable,nf90_get_var
+ use kinds, only: r_kind,r_single,i_kind
+ use gridmod, only: eta1_ll
+ use constants, only: zero,one,fv,zero_single,one_tenth,h300
+ use hybrid_ensemble_parameters, only: grd_ens,q_hyb_ens
+ use hybrid_ensemble_parameters, only: fv3sar_ensemble_opt
+
+ use mpimod, only: mpi_comm_world,mpi_rtype,mype
+ use netcdf_mod, only: nc_check
+ use gsi_rfv3io_mod,only: type_fv3regfilenameg
+ use gsi_rfv3io_mod,only:n2d
+ use constants, only: half,zero
+ use gsi_rfv3io_mod, only: gsi_fv3ncdf_read
+ use gsi_rfv3io_mod, only: gsi_fv3ncdf_read_v1
+ use gsi_rfv3io_mod, only: gsi_fv3ncdf_readuv
+ use gsi_rfv3io_mod, only: gsi_fv3ncdf_readuv_v1
+ use gsi_rfv3io_mod, only: gsi_fv3ncdf2d_read_v1
+ use gsi_bundlemod, only: gsi_gridcreate
+ use gsi_bundlemod, only: gsi_grid
+ use gsi_bundlemod, only: gsi_bundlecreate,gsi_bundledestroy
+ use gsi_bundlemod, only: gsi_bundlegetvar
+ use obsmod, only: if_model_dbz,if_model_fed
+ use gsi_rfv3io_mod, only: gsi_fv3ncdf_read_ens_parallel_over_ens,gsi_fv3ncdf_readuv_ens_parallel_over_ens
+
+
+
+ implicit none
+!
+! Declare passed variables
+ class(get_fv3_regional_ensperts_class), intent(inout) :: this
+ integer(i_kind), intent (in) :: iope
+ type (type_fv3regfilenameg) , intent (in) :: fv3_filenameginput
+ real(r_kind),dimension(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig),intent(out)::g_u,g_v,g_tv,g_rh,g_oz
+ real(r_kind),dimension(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig),optional,intent(out)::g_ql,g_qi,g_qr,g_dbz,g_fed
+ real(r_kind),dimension(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig),optional,intent(out)::g_qs,g_qg,g_qnr,g_w
+
+ real(r_kind),dimension(grd_ens%nlat,grd_ens%nlon),intent(out):: g_ps
+ real(r_kind),dimension(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig+1) ::g_prsi
+ real(r_kind),dimension(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig) ::g_prsl ,g_tsen,g_q,g_delp
+!
+! Declare local parameters
+ real(r_kind),parameter:: r0_01 = 0.01_r_kind
+ real(r_kind),parameter:: r10 = 10.0_r_kind
+ real(r_kind),parameter:: r100 = 100.0_r_kind
+ !
+! Declare local variables
+
+ integer(i_kind):: i,j,k,kp
+
+ integer(i_kind) iderivative
+
+
+ logical ice
+
+ character(len=24),parameter :: myname_ = 'general_read_fv3_regional'
+
+ character(len=:),allocatable :: grid_spec !='fv3_grid_spec'
+ character(len=:),allocatable :: ak_bk !='fv3_akbk'
+ character(len=:),allocatable :: dynvars !='fv3_dynvars'
+ character(len=:),allocatable :: phyvars !='fv3_phyvars'
+ character(len=:),allocatable :: tracers !='fv3_tracer'
+ character(len=:),allocatable :: sfcdata !='fv3_sfcdata'
+ character(len=:),allocatable :: couplerres!='coupler.res'
+
+
+ associate( this => this ) ! eliminates warning for unused dummy argument needed for binding
+ end associate
+
+ if( mype == iope )then
+ grid_spec=fv3_filenameginput%grid_spec
+ ak_bk=fv3_filenameginput%ak_bk
+ dynvars=fv3_filenameginput%dynvars
+ phyvars=fv3_filenameginput%phyvars
+ tracers=fv3_filenameginput%tracers
+ sfcdata=fv3_filenameginput%sfcdata
+ couplerres=fv3_filenameginput%couplerres
+
+ if(fv3sar_ensemble_opt == 0 ) then
+ call gsi_fv3ncdf_readuv_ens_parallel_over_ens(g_u,g_v,fv3_filenameginput,iope)
+ else
+ write(6,*) "Warning: we can only grab fields from restart files not cold start files for ensemble!"
+ endif
+
+ if(fv3sar_ensemble_opt == 0) then
+ if (if_model_dbz .or. if_model_fed) then
+ call gsi_fv3ncdf_read_ens_parallel_over_ens(fv3_filenameginput%dynvars,fv3_filenameginput,delp=g_delp,tsen=g_tsen,w=g_w,iope=iope)
+ call gsi_fv3ncdf_read_ens_parallel_over_ens(fv3_filenameginput%tracers,fv3_filenameginput,q=g_q,oz=g_oz,ql=g_ql,qr=g_qr,&
+ qs=g_qs,qi=g_qi,qg=g_qg,iope=iope)
+ if(if_model_dbz .and. if_model_fed) then
+ call gsi_fv3ncdf_read_ens_parallel_over_ens(fv3_filenameginput%phyvars,fv3_filenameginput,dbz=g_dbz,fed=g_fed,iope=iope)
+ elseif(if_model_dbz) then
+ call gsi_fv3ncdf_read_ens_parallel_over_ens(fv3_filenameginput%phyvars,fv3_filenameginput,dbz=g_dbz,iope=iope)
+ elseif(if_model_fed) then
+ call gsi_fv3ncdf_read_ens_parallel_over_ens(fv3_filenameginput%phyvars,fv3_filenameginput,fed=g_fed,iope=iope)
+ end if
+ else
+ call gsi_fv3ncdf_read_ens_parallel_over_ens(fv3_filenameginput%dynvars,fv3_filenameginput,delp=g_delp,tsen=g_tsen,iope=iope)
+ call gsi_fv3ncdf_read_ens_parallel_over_ens(fv3_filenameginput%tracers,fv3_filenameginput,q=g_q,oz=g_oz,iope=iope)
+ end if
+ else
+ write(6,*) "Warning: we can only grab fields from restart files not cold start files for ensemble!"
+ endif
+
+
+ if (fv3sar_ensemble_opt == 0) then
+ g_prsi(:,:,grd_ens%nsig+1)=eta1_ll(grd_ens%nsig+1) !thinkto be done , should use eta1_ll from ensemble grid
+ do i=grd_ens%nsig,1,-1
+ g_prsi(:,:,i)=g_delp(:,:,i)*0.001_r_kind+g_prsi(:,:,i+1)
+ enddo
+ g_ps(:,:)=g_prsi(:,:,1)
+
+ endif
+
+ !! tsen2tv !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ do k=1,grd_ens%nsig
+ do j=1,grd_ens%nlon
+ do i=1,grd_ens%nlat
+ g_tv(i,j,k)=g_tsen(i,j,k)*(one+fv*g_q(i,j,k))
+ enddo
+ enddo
+ enddo
+ if (.not.q_hyb_ens) then
+ ice=.true.
+ iderivative=0
+ do k=1,grd_ens%nsig
+ kp=k+1
+ do j=1,grd_ens%nlon
+ do i=1,grd_ens%nlat
+ g_prsl(i,j,k)=(g_prsi(i,j,k)+g_prsi(i,j,kp))*half
+ end do
+ end do
+ end do
+ call genqsat(g_rh,g_tsen(1,1,1),g_prsl(1,1,1),grd_ens%nlat,grd_ens%nlon,grd_ens%nsig,ice,iderivative)
+ do k=1,grd_ens%nsig
+ do j=1,grd_ens%nlon
+ do i=1,grd_ens%nlat
+ g_rh(i,j,k) = g_q(i,j,k)/g_rh(i,j,k)
+ end do
+ end do
+ end do
+ else
+ do k=1,grd_ens%nsig
+ do j=1,grd_ens%nlon
+ do i=1,grd_ens%nlat
+ g_rh(i,j,k) = g_q(i,j,k)
+ end do
+ end do
+ end do
+ end if
+ end if ! mype
+
+ return
+ end subroutine general_read_fv3_regional_parallel_over_ens
+
+
+ subroutine parallel_read_fv3_step2(this,mype,iope, &
+ g_ps,g_u,g_v,g_tv,g_rh,g_ql,g_oz,g_w,g_qr,g_qs,g_qi,&
+ g_qg,g_dbz,g_fed, &
+ gg_ps,gg_tv,gg_u,gg_v,gg_rh,gg_w,gg_dbz,gg_fed,gg_qr,&
+ gg_qs,gg_qi,gg_qg,gg_ql)
+
+ !$$$ subprogram documentation block
+ ! .
+ ! subprogram: parallel_read_fv3_step2 distribute all fields into all tasks
+ ! prgmmr: Y. Wang and X. Wang org: OU/MAP date: 2022-04-01
+ !
+ ! abstract: All fields have been read in by general_read_fv3_regional_parallel_over_ens.
+ ! Different tasks contain the data from different members.
+ ! This program will divided the full-domain fields into subdomains
+ ! and assign them to all tasks. poc: xuguang.wang@ou.edu
+ !
+ ! program history log:
+ !
+ ! 2022-04-01 Y. Wang and X. Wang - Changed from the code for WRF-ARW
+ !
+ ! input argument list:
+ !
+ ! output argument list:
+ !
+ ! attributes:
+ ! language: f90
+ ! machine: ibm RS/6000 SP
+ !
+ !$$$ end documentation block
+
+ use hybrid_ensemble_parameters, only: grd_ens
+ use mpimod, only: mpi_comm_world,ierror,mpi_rtype
+ use kinds, only: r_kind,r_single,i_kind
+ use constants, only: half,zero
+
+ implicit none
+
+ !
+ ! Declare passed variables
+ class(get_fv3_regional_ensperts_class), intent(inout) :: this
+ real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,grd_ens%nsig),intent(out):: &
+ g_u,g_v,g_tv,g_rh,g_ql,g_oz
+ real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,grd_ens%nsig),intent(out),optional::&
+ g_w,g_qr,g_qs,g_qi,g_qg,g_dbz,g_fed
+ integer(i_kind), intent(in) :: mype, iope
+ real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2),intent(out):: g_ps
+
+ ! The gg_ arrays are only sent by the rank doing I/O (mype==iope)
+ real(r_kind),optional,dimension(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig) :: &
+ gg_u,gg_v,gg_tv,gg_rh
+
+ real(r_kind),optional,dimension(grd_ens%nlat,grd_ens%nlon,grd_ens%nsig) :: &
+ gg_w,gg_dbz,gg_fed,gg_qr,gg_qs,gg_qi,gg_qg,gg_ql
+ real(r_kind),optional,dimension(grd_ens%nlat,grd_ens%nlon):: gg_ps
+
+ ! Declare local variables
+ real(r_kind),allocatable,dimension(:):: wrk_send_2d
+ integer(i_kind) :: k
+
+ ! transfer data from root to subdomains on each task
+ ! scatterv used, since full grids exist only on root task.
+ allocate(wrk_send_2d(grd_ens%itotsub))
+ g_oz=zero
+ ! first PS (output from fill_regional_2d is a column vector with a halo)
+ if(mype==iope) call this%fill_regional_2d(gg_ps,wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype, &
+ g_ps,grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ ! then TV,U,V,RH
+ do k=1,grd_ens%nsig
+ if (mype==iope) then
+ call this%fill_regional_2d(gg_tv(:,:,k),wrk_send_2d)
+ endif
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype, &
+ g_tv(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ if (mype==iope) call this%fill_regional_2d(gg_u(1,1,k),wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype, &
+ g_u(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ if (mype==iope) call this%fill_regional_2d(gg_v(1,1,k),wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype, &
+ g_v(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ if (mype==iope) call this%fill_regional_2d(gg_rh(1,1,k),wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype, &
+ g_rh(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ if( present(g_dbz) .or. present(g_fed) )then
+ if (mype==iope) call this%fill_regional_2d(gg_w(1,1,k),wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype, &
+ g_w(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ if (mype==iope) call this%fill_regional_2d(gg_qr(1,1,k),wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype,&
+ g_qr(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ if (mype==iope) call this%fill_regional_2d(gg_qs(1,1,k),wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype,&
+ g_qs(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ if (mype==iope) call this%fill_regional_2d(gg_qi(1,1,k),wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype,&
+ g_qi(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ if (mype==iope) call this%fill_regional_2d(gg_qg(1,1,k),wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype, &
+ g_qg(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ if (mype==iope) call this%fill_regional_2d(gg_ql(1,1,k),wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype,&
+ g_ql(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ if( present(g_dbz)) then
+ if (mype==iope) call this%fill_regional_2d(gg_dbz(1,1,k),wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype,&
+ g_dbz(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ end if
+ if( present(g_fed)) then
+ if (mype==iope) call this%fill_regional_2d(gg_fed(1,1,k),wrk_send_2d)
+ call mpi_scatterv(wrk_send_2d,grd_ens%ijn_s,grd_ens%displs_s,mpi_rtype,&
+ g_fed(1,1,k),grd_ens%ijn_s(mype+1),mpi_rtype,iope,mpi_comm_world,ierror)
+ end if
+ end if
+ enddo
+ deallocate(wrk_send_2d)
+ end subroutine parallel_read_fv3_step2
+
+ subroutine fill_regional_2d(fld_in,fld_out)
+ !$$$ subprogram documentation block
+ ! . . . .
+ ! subprogram: fill_regional_2d
+ ! prgmmr: mizzi org: ncar/mmm date: 2010-08-11
+ !
+ ! abstract: create a column vector for the subdomain (including halo)
+ ! from global 2d grid.
+ !
+ !
+ ! program history log:
+ ! 2010-08-11 parrish, initial documentation
+ ! 2012-03-12 whitaker, remove nx,ny,itotsub from argument list.
+ !
+ ! input argument list:
+ !
+ ! output argument list:
+ !
+ ! attributes:
+ ! language: f90
+ ! machine: ibm RS/6000 SP
+ !
+ !$$$ end documentation block
+ use kinds, only: r_kind,i_kind
+ use hybrid_ensemble_parameters, only: grd_ens
+ implicit none
+ real(r_kind),dimension(grd_ens%nlat,grd_ens%nlon)::fld_in
+ real(r_kind),dimension(grd_ens%itotsub)::fld_out
+ integer(i_kind):: i,j,k
+ do k=1,grd_ens%itotsub
+ i=grd_ens%ltosj_s(k)
+ j=grd_ens%ltosi_s(k)
+ fld_out(k)=fld_in(j,i)
+ enddo
+ return
+ end subroutine fill_regional_2d
+
subroutine ens_spread_dualres_regional_fv3_regional(this,mype,en_perts,nelen)
!$$$ subprogram documentation block
! . . . .
@@ -914,7 +1513,7 @@ subroutine ens_spread_dualres_regional_fv3_regional(this,mype,en_perts,nelen)
call stop2(9999)
endif
- sp_norm=(one/float(n_ens))
+ sp_norm=one/real(n_ens,r_kind)
sube%values=zero
!
diff --git a/src/gsi/cplr_get_pseudo_ensperts.f90 b/src/gsi/cplr_get_pseudo_ensperts.f90
index 9d12165409..f9566c1f45 100644
--- a/src/gsi/cplr_get_pseudo_ensperts.f90
+++ b/src/gsi/cplr_get_pseudo_ensperts.f90
@@ -487,7 +487,7 @@ subroutine get_pseudo_ensperts_wrf(this,en_perts,nelen)
deallocate(blend)
! Convert to mean
- bar_norm = one/float(n_ens)
+ bar_norm = one/real(n_ens,r_kind)
en_bar%values=en_bar%values*bar_norm
if(write_ens_sprd)then
@@ -1064,15 +1064,15 @@ subroutine get_bgtc_center(bc_lon,bc_lat)
close(32)
if(sn == 'S')then
- clat=- one * float(iclat)/10.0_r_kind
+ clat=- one * real(iclat,r_kind)/10.0_r_kind
else
- clat=float(iclat)/10.0_r_kind
+ clat=real(iclat,r_kind)/10.0_r_kind
endif
if(ew == 'W')then
- clon=360._r_kind - float(iclon)/10.0_r_kind
+ clon=360._r_kind - real(iclon,r_kind)/10.0_r_kind
else
- clon=float(iclon)/10.0_r_kind
+ clon=real(iclon,r_kind)/10.0_r_kind
endif
diff --git a/src/gsi/cplr_get_wrf_mass_ensperts.f90 b/src/gsi/cplr_get_wrf_mass_ensperts.f90
index 775c9c4195..7b6b3b9aa1 100644
--- a/src/gsi/cplr_get_wrf_mass_ensperts.f90
+++ b/src/gsi/cplr_get_wrf_mass_ensperts.f90
@@ -480,7 +480,7 @@ subroutine get_wrf_mass_ensperts_wrf(this,en_perts,nelen,ps_bar)
!
! CALCULATE ENSEMBLE MEAN
- bar_norm = one/float(n_ens)
+ bar_norm = one/real(n_ens,r_kind)
en_bar%values=en_bar%values*bar_norm
! Copy pbar to module array. ps_bar may be needed for vertical localization
@@ -2189,7 +2189,7 @@ subroutine ens_spread_dualres_regional_wrf(this,mype,en_perts,nelen,en_bar)
call stop2(999)
endif
- sp_norm=(one/float(n_ens))
+ sp_norm=one/real(n_ens,r_kind)
sube%values=zero
!
diff --git a/src/gsi/cplr_get_wrf_nmm_ensperts.f90 b/src/gsi/cplr_get_wrf_nmm_ensperts.f90
index 3e30822639..c9179eedb9 100644
--- a/src/gsi/cplr_get_wrf_nmm_ensperts.f90
+++ b/src/gsi/cplr_get_wrf_nmm_ensperts.f90
@@ -859,7 +859,7 @@ subroutine get_wrf_nmm_ensperts_wrf(this,en_perts,nelen,region_lat_ens,region_lo
!
! CALCULATE ENSEMBLE MEAN
- bar_norm = one/float(n_ens)
+ bar_norm = one/real(n_ens,r_kind)
en_bar%values=en_bar%values*bar_norm
! Copy pbar to module array. ps_bar may be needed for vertical localization
diff --git a/src/gsi/cplr_gfs_ensmod.f90 b/src/gsi/cplr_gfs_ensmod.f90
index c16c0e8c0e..55ac32fce4 100644
--- a/src/gsi/cplr_gfs_ensmod.f90
+++ b/src/gsi/cplr_gfs_ensmod.f90
@@ -16,12 +16,23 @@ module get_gfs_ensmod_mod
! machine: ibm RS/6000 SP
!
!$$$
+ use kinds, only: i_kind,r_kind,r_single
use mpeu_util, only: die
use mpimod, only: mype,npe
use abstract_ensmod, only: this_ens_class => abstractEnsemble
+ use genex_mod, only: genex_info
implicit none
private
+
+ integer(i_kind) :: ias,iae,iasm,iaem,iaemz,jas,jae,jasm,jaem,jaemz
+ integer(i_kind) :: kas,kae,kasm,kaem,kaemz,mas,mae,masm,maem,maemz
+ integer(i_kind) :: ibs,ibe,ibsm,ibem,ibemz,jbs,jbe,jbsm,jbem,jbemz
+ integer(i_kind) :: kbs,kbe,kbsm,kbem,kbemz,mbs,mbe,mbsm,mbem,mbemz
+ integer(i_kind) :: icw,iql,iqi,iqr,iqs,iqg
+ integer(i_kind) :: n2d
+ type(genex_info) :: s_a2b
+
public :: ensemble
public :: ensemble_typemold
@@ -84,7 +95,6 @@ subroutine get_gfs_Nens(this,grd,members,ntindex,atm_bundle,iret)
!
!$$$
- use kinds, only: i_kind,r_kind,r_single
use gridmod, only: use_gfs_nemsio, use_gfs_ncio
use general_sub2grid_mod, only: sub2grid_info
use hybrid_ensemble_parameters, only: ens_fast_read
@@ -153,10 +163,10 @@ subroutine get_user_ens_gfs_fastread_(ntindex,atm_bundle, &
!
! input argument list:
! ntindex - time index for ensemble
-! ens_atm_bundle - atm bundle w/ fields for ensemble
+! atm_bundle - atm bundle w/ fields for ensemble
!
! output argument list:
-! ens_atm_bundle - atm bundle w/ fields for ensemble
+! atm_bundle - atm bundle w/ fields for ensemble
! iret - return code, 0 for successful read.
!
! attributes:
@@ -166,18 +176,18 @@ subroutine get_user_ens_gfs_fastread_(ntindex,atm_bundle, &
!$$$
use mpimod, only: mpi_comm_world,ierror,mpi_real8,mpi_integer4,mpi_max
- use kinds, only: i_kind,r_single,r_kind
use constants, only: zero
use general_sub2grid_mod, only: sub2grid_info,general_sub2grid_destroy_info
use gsi_4dvar, only: ens_fhrlevs
use gsi_bundlemod, only: gsi_bundle
- use hybrid_ensemble_parameters, only: n_ens,grd_ens
+ use gsi_bundlemod, only : assignment(=)
+ use hybrid_ensemble_parameters, only: n_ens,grd_ens,ntlevs_ens
use hybrid_ensemble_parameters, only: ensemble_path
- use control_vectors, only: nc2d,nc3d
- !use control_vectors, only: cvars2d,cvars3d
- use genex_mod, only: genex_info,genex_create_info,genex,genex_destroy_info
+ use control_vectors, only: cvars2d,cvars3d,nc2d,nc3d
+ use genex_mod, only: genex_create_info,genex,genex_destroy_info
use gridmod, only: use_gfs_nemsio
use jfunc, only: cnvw_option
+ use mpeu_util, only: getindex
implicit none
@@ -193,18 +203,13 @@ subroutine get_user_ens_gfs_fastread_(ntindex,atm_bundle, &
character(len=*),parameter :: myname_='get_user_ens_gfs_fastread_'
character(len=70) :: filename
character(len=70) :: filenamesfc
- integer(i_kind) :: i,ii,j,jj,k,n
+ integer(i_kind) :: i,ii,j,k,n
integer(i_kind) :: io_pe,n_io_pe_s,n_io_pe_e,n_io_pe_em,i_ens
- integer(i_kind) :: ip,ips,ipe,jps,jpe
- integer(i_kind) :: ias,iae,iasm,iaem,iaemz,jas,jae,jasm,jaem,jaemz
- integer(i_kind) :: kas,kae,kasm,kaem,kaemz,mas,mae,masm,maem,maemz
- integer(i_kind) :: ibs,ibe,ibsm,ibem,ibemz,jbs,jbe,jbsm,jbem,jbemz
- integer(i_kind) :: kbs,kbe,kbsm,kbem,kbemz,mbs,mbe,mbsm,mbem,mbemz
- integer(i_kind) :: n2d
+ integer(i_kind) :: ip
integer(i_kind) :: nlon,nlat,nsig
- type(genex_info) :: s_a2b
+ integer(i_kind),dimension(n_ens) :: io_pe0,iretx
real(r_single),allocatable,dimension(:,:,:,:) :: en_full,en_loc
- real(r_kind),allocatable,dimension(:,:,:) :: en_loc3
+ real(r_single),allocatable,dimension(:,:,:) :: sloc
integer(i_kind),allocatable,dimension(:) :: m_cvars2dw,m_cvars3dw
integer(i_kind) :: m_cvars2d(nc2d),m_cvars3d(nc3d)
type(sub2grid_info) :: grd3d
@@ -214,61 +219,72 @@ subroutine get_user_ens_gfs_fastread_(ntindex,atm_bundle, &
nlon=grd_ens%nlon
nsig=grd_ens%nsig
+ if(ntindex == 1)then
! set up partition of available processors for parallel read
- if ( n_ens > npe ) &
- call die(myname_, ': ***ERROR*** CANNOT READ ENSEMBLE n_ens > npe, increase npe >= n_ens', 99)
+ if ( n_ens > npe ) &
+ call die(myname_, ': ***ERROR*** CANNOT READ ENSEMBLE n_ens > npe, increase npe >= n_ens', 99)
- call ens_io_partition_(n_ens,ntindex,io_pe,n_io_pe_s,n_io_pe_e,n_io_pe_em,i_ens)
- ! setup communicator for scatter to subdomains:
+ call ens_io_partition_(n_ens,io_pe,n_io_pe_s,n_io_pe_e,n_io_pe_em,io_pe0,i_ens)
- ! first, define gsi subdomain boundaries in global units:
-
- ip=1 ! halo width is hardwired at 1
- ips=grd_ens%istart(mype+1)
- ipe=ips+grd_ens%lat1-1
- jps=grd_ens%jstart(mype+1)
- jpe=jps+grd_ens%lon1-1
+ ! setup communicator for scatter to subdomains:
+ ! first, define gsi subdomain boundaries in global units:
!!!!!!!!!!!!NOTE--FOLLOWING HAS MANY VARS TO BE DEFINED--NLAT,NLON ARE ENSEMBLE DOMAIN DIMS
!!!!!!!!for example, n2d = nc3d*nsig + nc2d
- n2d=nc3d*grd_ens%nsig+nc2d
- ias=1 ; iae=0 ; jas=1 ; jae=0 ; kas=1 ; kae=0 ; mas=1 ; mae=0
- if(mype==io_pe) then
- iae=nlat
- jae=nlon
- kae=n2d
- mas=n_io_pe_s ; mae=n_io_pe_em
- endif
- iasm=ias ; iaem=iae ; jasm=jas ; jaem=jae ; kasm=kas ; kaem=kae ; masm=mas ; maem=mae
-
- ibs =ips ; ibe =ipe ; jbs =jps ; jbe =jpe
- ibsm=ibs-ip ; ibem=ibe+ip ; jbsm=jbs-ip ; jbem=jbe+ip
- kbs =1 ; kbe =n2d ; mbs =1 ; mbe =n_ens
- kbsm=kbs ; kbem=kbe ; mbsm=mbs ; mbem=mbe
- iaemz=max(iasm,iaem) ; jaemz=max(jasm,jaem)
- kaemz=max(kasm,kaem) ; maemz=max(masm,maem)
- ibemz=max(ibsm,ibem) ; jbemz=max(jbsm,jbem)
- kbemz=max(kbsm,kbem) ; mbemz=max(mbsm,mbem)
- call genex_create_info(s_a2b,ias ,iae ,jas ,jae ,kas ,kae ,mas ,mae , &
- ibs ,ibe ,jbs ,jbe ,kbs ,kbe ,mbs ,mbe , &
- iasm,iaem,jasm,jaem,kasm,kaem,masm,maem, &
- ibsm,ibem,jbsm,jbem,kbsm,kbem,mbsm,mbem)
-
- write(filename,22) trim(adjustl(ensemble_path)),ens_fhrlevs(ntindex),mas
-22 format(a,'sigf',i2.2,'_ens_mem',i3.3)
+ n2d=nc3d*grd_ens%nsig+nc2d
+ ias=0 ; iae=0 ; jas=0 ; jae=0 ; kas=1 ; kae=0 ; mas=1 ; mae=0
+ if(mype==io_pe) then
+ iae=nlat+1
+ jae=nlon+1
+ kae=n2d
+ mas=n_io_pe_s ; mae=n_io_pe_em
+ endif
+ iasm=ias ; iaem=iae ; jasm=jas ; jaem=jae ; kasm=kas ; kaem=kae ; masm=mas ; maem=mae
+
+ ip=1 ! halo width is hardwired at 1
+ ibs=grd_ens%istart(mype+1)
+ ibe=ibs+grd_ens%lat1-1
+ jbs=grd_ens%jstart(mype+1)
+ jbe=jbs+grd_ens%lon1-1
+ jbs=jbs-1
+ jbe=jbe+1
+ ibs=ibs-1
+ ibe=ibe+1
+
+ ibsm=ibs ; ibem=ibe ; jbsm=jbs ; jbem=jbe
+
+ kbs =1 ; kbe =n2d ; mbs =1 ; mbe =n_ens
+ kbsm=kbs ; kbem=kbe ; mbsm=mbs ; mbem=mbe
+ iaemz=max(iasm,iaem) ; jaemz=max(jasm,jaem)
+ kaemz=max(kasm,kaem) ; maemz=max(masm,maem)
+ ibemz=max(ibsm,ibem) ; jbemz=max(jbsm,jbem)
+ kbemz=max(kbsm,kbem) ; mbemz=max(mbsm,mbem)
+ call genex_create_info(s_a2b,ias ,iae ,jas ,jae ,kas ,kae ,mas ,mae , &
+ ibs ,ibe ,jbs ,jbe ,kbs ,kbe ,mbs ,mbe , &
+ iasm,iaem,jasm,jaem,kasm,kaem,masm,maem, &
+ ibsm,ibem,jbsm,jbem,kbsm,kbem,mbsm,mbem)
+
+ if(mype==0)then
+ do n=1,n_ens
+ write(6,'(3(a,1x,i5,1x))') 'reading ensemble member', n,'on pe', io_pe0(n)
+ enddo
+ end if
+ end if
+ if(mype==0) write(6,*) ' reading time level ',ntindex
allocate(m_cvars2dw(nc2din),m_cvars3dw(nc3din))
m_cvars2dw=-999
m_cvars3dw=-999
- allocate(en_full(iasm:iaemz,jasm:jaemz,kasm:kaemz,masm:maemz))
-
!! read ensembles
if ( mas == mae ) then
+ allocate(en_full(iasm:iaemz,jasm:jaemz,kasm:kaemz,masm:maemz))
+ write(filename,22) trim(adjustl(ensemble_path)),ens_fhrlevs(ntindex),mas
+22 format(a,'sigf',i2.2,'_ens_mem',i3.3)
if ( use_gfs_nemsio ) then
if (cnvw_option) then
write(filenamesfc,23) trim(adjustl(ensemble_path)),ens_fhrlevs(ntindex),mas
@@ -284,50 +300,61 @@ subroutine get_user_ens_gfs_fastread_(ntindex,atm_bundle, &
filename,.true.)
end if
else
- call parallel_read_gfsnc_state_(en_full,m_cvars2dw,m_cvars3dw,nlon,nlat,nsig, &
+ call parallel_read_gfsnc_state_(en_full,m_cvars2dw,m_cvars3dw,nlon,nlat,nsig, &
ias,jas,mas, &
iasm,iaemz,jasm,jaemz,kasm,kaemz,masm,maemz, &
filename)
end if
+ else
+ allocate(en_full(1,1,1,1))
end if
+! scatter to subdomains:
+
call mpi_allreduce(m_cvars2dw,m_cvars2d,nc2d,mpi_integer4,mpi_max,mpi_comm_world,ierror)
call mpi_allreduce(m_cvars3dw,m_cvars3d,nc3d,mpi_integer4,mpi_max,mpi_comm_world,ierror)
-
deallocate(m_cvars2dw,m_cvars3dw)
-! scatter to subdomains:
- allocate(en_loc(ibsm:ibemz,jbsm:jbemz,kbsm:kbemz,mbsm:mbemz))
+ ! Check hydrometeors in control variables
+ icw=getindex(cvars3d,'cw')
+ iql=getindex(cvars3d,'ql')
+ iqi=getindex(cvars3d,'qi')
+ iqr=getindex(cvars3d,'qr')
+ iqs=getindex(cvars3d,'qs')
+ iqg=getindex(cvars3d,'qg')
+
+! en_loc=zero
- en_loc=zero
+ allocate(en_loc(ibsm:ibemz,jbsm:jbemz,kbsm:kbemz,mbsm:mbemz))
call genex(s_a2b,en_full,en_loc)
deallocate(en_full)
- call genex_destroy_info(s_a2b) ! check on actual routine name
-! transfer en_loc to en_loc3 then to atm_bundle
+ if(ntindex == ntlevs_ens)call genex_destroy_info(s_a2b)
- allocate(en_loc3(lat2in,lon2in,nc2d+nc3d*nsig))
- iret = 0
call create_grd23d_(grd3d,nc2d+nc3d*grd%nsig)
+
+
+ allocate(sloc(grd3d%lat2,grd3d%lon2,grd3d%num_fields))
+ iretx=0
+!$omp parallel do schedule(dynamic,1) private(n,k,j,i,sloc)
do n=1,n_ens
- do k=1,nc2d+nc3d*nsig
- jj=0
- do j=jbsm,jbem
- jj=jj+1
- ii=0
- do i=ibsm,ibem
- ii=ii+1
- en_loc3(ii,jj,k)=en_loc(i,j,k,n)
+ do k=1,grd3d%num_fields
+ do j=1,grd3d%lon2
+ do i=1,grd3d%lat2
+ sloc(i,j,k)=en_loc(i+ibsm-1,j+jbsm-1,k,n)
enddo
enddo
enddo
- call move2bundle_(grd3d,en_loc3,atm_bundle(n),m_cvars2d,m_cvars3d,iret)
+ call move2bundle_(grd3d,sloc,atm_bundle(n),m_cvars2d,m_cvars3d,iretx(n))
enddo
+ iret=iretx(1)
+ do n=2,n_ens
+ iret=iret+iretx(n)
+ end do
+ deallocate(en_loc,sloc)
call general_sub2grid_destroy_info(grd3d,grd)
- deallocate(en_loc,en_loc3)
-
end subroutine get_user_ens_gfs_fastread_
@@ -347,7 +374,7 @@ subroutine move2bundle_(grd3d,en_loc3,atm_bundle,m_cvars2d,m_cvars3d,iret)
!
! input argument list:
! grd - grd info for ensemble
-! en_loc3 - ensemble member
+! sloc - ensemble member
! atm_bundle - empty atm bundle
! m_cvars2d - maps 3rd index in en_loc3 for start of each 2d variable
! m_cvars3d - maps 3rd index in en_loc3 for start of each 3d variable
@@ -361,56 +388,36 @@ subroutine move2bundle_(grd3d,en_loc3,atm_bundle,m_cvars2d,m_cvars3d,iret)
!
!$$$
- use kinds, only: i_kind,r_kind,r_single
- use constants, only: zero,one,two,fv
use general_sub2grid_mod, only: sub2grid_info
use hybrid_ensemble_parameters, only: en_perts
use gsi_bundlemod, only: gsi_bundle
use gsi_bundlemod, only: gsi_bundlegetpointer
- use gsi_bundlemod, only : assignment(=)
use control_vectors, only: cvars2d,cvars3d,nc2d,nc3d
- use mpeu_util, only: getindex
implicit none
! Declare passed variables
type(sub2grid_info), intent(in ) :: grd3d
- real(r_kind), intent(inout) :: en_loc3(grd3d%lat2,grd3d%lon2,nc2d+nc3d*grd3d%nsig)
type(gsi_bundle), intent(inout) :: atm_bundle
+ real(r_single), intent(inout) :: en_loc3(grd3d%lat2,grd3d%lon2,grd3d%num_fields)
integer(i_kind), intent(in ) :: m_cvars2d(nc2d),m_cvars3d(nc3d)
- integer(i_kind), intent( out) :: iret
+ integer(i_kind), intent(inout) :: iret
! Declare internal variables
character(len=*),parameter :: myname_='move2bundle_'
- character(len=70) :: filename
- integer(i_kind) :: ierr
- integer(i_kind) :: km,m
- integer(i_kind) :: icw,iql,iqi,iqr,iqs,iqg
- real(r_kind),pointer,dimension(:,:) :: ps
+ integer(i_kind) :: ierr,i,j
+ integer(i_kind) :: km1,m
+ real(r_single),pointer,dimension(:,:) :: ps
!real(r_kind),pointer,dimension(:,:) :: sst
- real(r_kind),pointer,dimension(:,:,:) :: u,v,tv,q,oz,cwmr
- real(r_kind),pointer,dimension(:,:,:) :: qlmr,qimr,qrmr,qsmr,qgmr
- real(r_kind),parameter :: r0_001 = 0.001_r_kind
+ real(r_single),pointer,dimension(:,:,:) :: u,v,tv,q,oz,cwmr
+ real(r_single),pointer,dimension(:,:,:) :: qlmr,qimr,qrmr,qsmr,qgmr
-
-!--- now update halo values of all variables using general_sub2grid
- call update_halos_(grd3d,en_loc3)
-
- ! Check hydrometeors in control variables
- icw=getindex(cvars3d,'cw')
- iql=getindex(cvars3d,'ql')
- iqi=getindex(cvars3d,'qi')
- iqr=getindex(cvars3d,'qr')
- iqs=getindex(cvars3d,'qs')
- iqg=getindex(cvars3d,'qg')
-
-! initialize atm_bundle to zero
-
- atm_bundle=zero
+! atm_bundle to zero done earlier
call gsi_bundlegetpointer(atm_bundle,'ps',ps, ierr); iret = ierr
- !call gsi_bundlegetpointer(atm_bundle,'sst',sst, ierr); iret = ierr
+ !call gsi_bundlegetpointer(atm_bundle,'sst',sst, ierr); iret = iret+ierr
+
call gsi_bundlegetpointer(atm_bundle,'sf',u , ierr); iret = ierr + iret
call gsi_bundlegetpointer(atm_bundle,'vp',v , ierr); iret = ierr + iret
call gsi_bundlegetpointer(atm_bundle,'t' ,tv, ierr); iret = ierr + iret
@@ -425,59 +432,54 @@ subroutine move2bundle_(grd3d,en_loc3,atm_bundle,m_cvars2d,m_cvars3d,iret)
if ( iret /= 0 ) then
if ( mype == 0 ) then
write(6,'(A)') trim(myname_) // ': ERROR!'
- write(6,'(A)') trim(myname_) // ': For now, GFS requires all MetFields: ps,u,v,(sf,vp)tv,q,oz,cw'
+ write(6,'(A)') trim(myname_) // ': For now, GFS requires all MetFields: ps,u,v,(sf,vp)tv,q,oz'
write(6,'(A)') trim(myname_) // ': but some have not been found. Aborting ... '
write(6,'(A)') trim(myname_) // ': WARNING!'
- write(6,'(3A,I5)') trim(myname_) // ': Trouble reading ensemble file : ', trim(filename), ', IRET = ', iret
endif
return
endif
-
do m=1,nc2d
! convert ps from Pa to cb
- if(trim(cvars2d(m))=='ps') ps=r0_001*en_loc3(:,:,m_cvars2d(m))
+ if(trim(cvars2d(m))=='ps') ps=en_loc3(:,:,m_cvars2d(m))
! if(trim(cvars2d(m))=='sst') sst=en_loc3(:,:,m_cvars2d(m)) !no sst for now
enddo
- km = en_perts(1,1,1)%grid%km
-!$omp parallel do schedule(dynamic,1) private(m)
+ km1 = en_perts(1,1,1)%grid%km - 1
do m=1,nc3d
if(trim(cvars3d(m))=='sf')then
- u = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km)
+ u = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km1)
else if(trim(cvars3d(m))=='vp') then
- v = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km)
+ v = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km1)
else if(trim(cvars3d(m))=='t') then
- tv = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km)
+! Note tv here is sensible temperature. Converted to virtual temperature
+! later.
+ tv = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km1)
else if(trim(cvars3d(m))=='q') then
- q = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km)
+ q = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km1)
else if(trim(cvars3d(m))=='oz') then
- oz = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km)
+ oz = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km1)
else if(trim(cvars3d(m))=='cw') then
- cwmr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km)
+ cwmr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km1)
else if(trim(cvars3d(m))=='ql') then
- qlmr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km)
+ qlmr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km1)
else if(trim(cvars3d(m))=='qi') then
- qimr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km)
+ qimr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km1)
else if(trim(cvars3d(m))=='qr') then
- qrmr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km)
+ qrmr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km1)
else if(trim(cvars3d(m))=='qs') then
- qsmr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km)
+ qsmr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km1)
else if(trim(cvars3d(m))=='qg') then
- qgmr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km)
+ qgmr = en_loc3(:,:,m_cvars3d(m):m_cvars3d(m)+km1)
end if
enddo
-! convert t to virtual temperature
- tv=tv*(one+fv*q)
-
return
end subroutine move2bundle_
subroutine create_grd23d_(grd23d,nvert)
- use kinds, only: i_kind
use general_sub2grid_mod, only: sub2grid_info,general_sub2grid_create_info
use hybrid_ensemble_parameters, only: grd_ens
@@ -498,83 +500,28 @@ subroutine create_grd23d_(grd23d,nvert)
end subroutine create_grd23d_
-subroutine update_halos_(grd,s)
-
- use kinds, only: i_kind,r_kind
- use general_sub2grid_mod, only: sub2grid_info,general_sub2grid,general_grid2sub
-
- implicit none
-
- ! Declare passed variables
- type(sub2grid_info), intent(in ) :: grd
- real(r_kind), intent(inout) :: s(grd%lat2,grd%lon2,grd%num_fields)
-
- ! Declare local variables
- integer(i_kind) inner_vars,lat2,lon2,nlat,nlon,nvert,kbegin_loc,kend_loc,kend_alloc
- integer(i_kind) ii,i,j,k
- real(r_kind),allocatable,dimension(:) :: sloc
- real(r_kind),allocatable,dimension(:,:,:,:) :: work
-
- lat2=grd%lat2
- lon2=grd%lon2
- nlat=grd%nlat
- nlon=grd%nlon
- nvert=grd%num_fields
- inner_vars=grd%inner_vars
- kbegin_loc=grd%kbegin_loc
- kend_loc=grd%kend_loc
- kend_alloc=grd%kend_alloc
- allocate(sloc(lat2*lon2*nvert))
- allocate(work(inner_vars,nlat,nlon,kbegin_loc:kend_alloc))
- ii=0
- do k=1,nvert
- do j=1,lon2
- do i=1,lat2
- ii=ii+1
- sloc(ii)=s(i,j,k)
- enddo
- enddo
- enddo
- call general_sub2grid(grd,sloc,work)
-
- call general_grid2sub(grd,work,sloc)
- ii=0
- do k=1,nvert
- do j=1,lon2
- do i=1,lat2
- ii=ii+1
- s(i,j,k)=sloc(ii)
- enddo
- enddo
- enddo
-
- deallocate(sloc,work)
-
-end subroutine update_halos_
-
-subroutine ens_io_partition_(n_ens,ntindex,io_pe,n_io_pe_s,n_io_pe_e,n_io_pe_em,i_ens)
+subroutine ens_io_partition_(n_ens,io_pe,n_io_pe_s,n_io_pe_e,n_io_pe_em,io_pe0,i_ens)
! do computation on all processors, then assign final local processor
! values.
- use kinds, only: r_kind,i_kind
use constants, only: half
implicit none
! Declare passed variables
- integer(i_kind),intent(in ) :: n_ens,ntindex
+ integer(i_kind),intent(in ) :: n_ens
integer(i_kind),intent( out) :: io_pe,n_io_pe_s,n_io_pe_e,n_io_pe_em,i_ens
+ integer(i_kind),intent( out) :: io_pe0(n_ens)
! Declare local variables
- integer(i_kind) :: io_pe0(n_ens)
integer(i_kind) :: iskip,jskip,nextra,ipe,n
integer(i_kind) :: nsig
i_ens=-1
nsig=1
iskip=npe/n_ens
- nextra=npe-iskip*n_ens
+ nextra=npe-iskip*(n_ens-1)-1
jskip=iskip
io_pe=-1
io_pe0=-1
@@ -589,13 +536,12 @@ subroutine ens_io_partition_(n_ens,ntindex,io_pe,n_io_pe_s,n_io_pe_e,n_io_pe_em,
else
jskip=iskip
endif
+ if(ipe > npe) then
+ write(6,*)' ens_io_partition_: ***ERROR*** ',ipe,jskip,' processor error: PROGRAM STOPS'
+ call stop2(999)
+ end if
ipe=ipe+jskip
enddo
- if(mype==0)then
- do n=1,n_ens
- write(6,'(3(a,1x,i5,1x))') 'reading ensemble member', n,' time level',ntindex,'on pe', io_pe0(n)
- enddo
- end if
do n=1,n_ens
if(mype==io_pe0(n)) then
@@ -609,12 +555,11 @@ subroutine ens_io_partition_(n_ens,ntindex,io_pe,n_io_pe_s,n_io_pe_e,n_io_pe_em,
end subroutine ens_io_partition_
-subroutine parallel_read_nemsio_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsig, &
+subroutine parallel_read_nemsio_state_(en_full,m_cvars2dw,m_cvars3d,nlon,nlat,nsig, &
ias,jas,mas, &
iasm,iaemz,jasm,jaemz,kasm,kaemz,masm,maemz, &
filename,init_head,filenamesfc)
- use kinds, only: i_kind,r_kind,r_single
use constants, only: r60,r3600,zero,one,half,deg2rad
use nemsio_module, only: nemsio_init,nemsio_open,nemsio_close
use ncepnems_io, only: error_msg,imp_physics
@@ -632,7 +577,7 @@ subroutine parallel_read_nemsio_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsi
integer(i_kind), intent(in ) :: nlon,nlat,nsig
integer(i_kind), intent(in ) :: ias,jas,mas
integer(i_kind), intent(in ) :: iasm,iaemz,jasm,jaemz,kasm,kaemz,masm,maemz
- integer(i_kind), intent(inout) :: m_cvars2d(nc2d),m_cvars3d(nc3d)
+ integer(i_kind), intent(inout) :: m_cvars2dw(nc2d),m_cvars3d(nc3d)
real(r_single), intent(inout) :: en_full(iasm:iaemz,jasm:jaemz,kasm:kaemz,masm:maemz)
character(len=*), intent(in ) :: filename
character(len=*), optional, intent(in) :: filenamesfc
@@ -641,7 +586,6 @@ subroutine parallel_read_nemsio_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsi
! Declare local variables
integer(i_kind) i,ii,j,jj,k,lonb,latb,levs,latb2,lonb2
integer(i_kind) k2,k3,k3u,k3v,k3t,k3q,k3cw,k3oz,kf
- integer(i_kind) k3ql,k3qi,k3qr,k3qs,k3qg
integer(i_kind) iret
integer(i_kind) :: istop = 101
integer(i_kind),dimension(7):: idate
@@ -717,7 +661,8 @@ subroutine parallel_read_nemsio_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsi
enddo
deallocate(rlons)
- fhour = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
odate(3) = idate(3) !day
@@ -726,23 +671,40 @@ subroutine parallel_read_nemsio_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsi
allocate(work(nlon*(nlat-2)))
if (imp_physics == 11) allocate(work2(nlon*(nlat-2)))
allocate(temp3(nlat,nlon,nsig,nc3d))
- allocate(temp2(nlat,nlon,nc2d))
+ temp3=zero
k3u=0 ; k3v=0 ; k3t=0 ; k3q=0 ; k3cw=0 ; k3oz=0
- k3ql=0; k3qi=0; k3qr=0; k3qs=0; k3qg=0
do k3=1,nc3d
- if(cvars3d(k3)=='sf') k3u=k3
- if(cvars3d(k3)=='vp') k3v=k3
- if(cvars3d(k3)=='t') k3t=k3
- if(cvars3d(k3)=='q') k3q=k3
- if(cvars3d(k3)=='cw') k3cw=k3
- if(cvars3d(k3)=='oz') k3oz=k3
- if(cvars3d(k3)=='ql') k3ql=k3
- if(cvars3d(k3)=='qi') k3qi=k3
- if(cvars3d(k3)=='qr') k3qr=k3
- if(cvars3d(k3)=='qs') k3qs=k3
- if(cvars3d(k3)=='qg') k3qg=k3
do k=1,nsig
- if(trim(cvars3d(k3))=='cw') then
+ if(trim(cvars3d(k3))=='t') then
+ k3t=k3
+ call nemsio_readrecv(gfile,'tmp','mid layer',k,work,iret=iret)
+ if (iret /= 0) call error_msg(trim(myname_),trim(filename),'tmp','read',istop+3,iret,.true.)
+ call move1_(work,temp3(:,:,k,k3),nlon,nlat)
+ call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
+ elseif(trim(cvars3d(k3))=='sf') then
+ k3u=k3
+ call nemsio_readrecv(gfile,'ugrd','mid layer',k,work,iret=iret)
+ if (iret /= 0) call error_msg(trim(myname_),trim(filename),'ugrd','read',istop+1,iret,.true.)
+ call move1_(work,temp3(:,:,k,k3),nlon,nlat)
+ elseif(trim(cvars3d(k3))=='vp') then
+ k3v=k3
+ call nemsio_readrecv(gfile,'vgrd','mid layer',k,work,iret=iret)
+ if (iret /= 0) call error_msg(trim(myname_),trim(filename),'vgrd','read',istop+2,iret,.true.)
+ call move1_(work,temp3(:,:,k,k3),nlon,nlat)
+ elseif(trim(cvars3d(k3))=='q') then
+ k3q=k3
+ call nemsio_readrecv(gfile,'spfh','mid layer',k,work,iret=iret)
+ if (iret /= 0) call error_msg(trim(myname_),trim(filename),trim(cvars3d(k3)),'read',istop+4,iret,.true.)
+ call move1_(work,temp3(:,:,k,k3),nlon,nlat)
+ call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
+ elseif(trim(cvars3d(k3))=='oz') then
+ k3oz=k3
+ call nemsio_readrecv(gfile,'o3mr','mid layer',k,work,iret=iret)
+ if (iret /= 0) call error_msg(trim(myname_),trim(filename),'o3mr','read',istop+5,iret,.true.)
+ call move1_(work,temp3(:,:,k,k3),nlon,nlat)
+ call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
+ elseif(trim(cvars3d(k3))=='cw') then
+ k3cw=k3
call nemsio_readrecv(gfile,'clwmr','mid layer',k,work,iret=iret)
if (iret /= 0) call error_msg(trim(myname_),trim(filename),'clwmr','read',istop+6,iret,.true.)
if (imp_physics == 11) then
@@ -789,30 +751,7 @@ subroutine parallel_read_nemsio_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsi
if (iret /= 0) call error_msg(trim(myname_),trim(filename),'grle','read',istop+12,iret)
call move1_(work,temp3(:,:,k,k3),nlon,nlat)
call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- elseif(trim(cvars3d(k3))=='oz') then
- call nemsio_readrecv(gfile,'o3mr','mid layer',k,work,iret=iret)
- if (iret /= 0) call error_msg(trim(myname_),trim(filename),'o3mr','read',istop+5,iret,.true.)
- call move1_(work,temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- elseif(trim(cvars3d(k3))=='q') then
- call nemsio_readrecv(gfile,'spfh','mid layer',k,work,iret=iret)
- if (iret /= 0) call error_msg(trim(myname_),trim(filename),trim(cvars3d(k3)),'read',istop+4,iret,.true.)
- call move1_(work,temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- elseif(trim(cvars3d(k3))=='t') then
- call nemsio_readrecv(gfile,'tmp','mid layer',k,work,iret=iret)
- if (iret /= 0) call error_msg(trim(myname_),trim(filename),'tmp','read',istop+3,iret,.true.)
- call move1_(work,temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- elseif(trim(cvars3d(k3))=='sf') then
- call nemsio_readrecv(gfile,'ugrd','mid layer',k,work,iret=iret)
- if (iret /= 0) call error_msg(trim(myname_),trim(filename),'ugrd','read',istop+1,iret,.true.)
- call move1_(work,temp3(:,:,k,k3),nlon,nlat)
- elseif(trim(cvars3d(k3))=='vp') then
- call nemsio_readrecv(gfile,'vgrd','mid layer',k,work,iret=iret)
- if (iret /= 0) call error_msg(trim(myname_),trim(filename),'vgrd','read',istop+2,iret,.true.)
- call move1_(work,temp3(:,:,k,k3),nlon,nlat)
- endif
+ end if
enddo
enddo
do k=1,nsig
@@ -822,10 +761,41 @@ subroutine parallel_read_nemsio_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsi
if (k3u==0.or.k3v==0.or.k3t==0.or.k3q==0.or.k3oz==0) &
write(6,'(" WARNING, problem with one of k3-")')
+! move temp3 to en_full
+ kf=0
+ do k3=1,nc3d
+ m_cvars3d(k3)=kf+1
+ do k=1,nsig
+ kf=kf+1
+ jj=jas
+ do j=1,nlon
+ jj=jj+1
+ ii=ias
+ do i=1,nlat
+ ii=ii+1
+ en_full(ii,jj,kf,mas)=temp3(i,j,k,k3)
+ enddo
+ enddo
+ ii=ias
+ do i=1,nlat
+ ii=ii+1
+ en_full(ii,jasm,kf,mas)=en_full(ii,jaem-1,kf,mas)
+ en_full(ii,jaem,kf,mas)=en_full(ii,jasm+1,kf,mas)
+ enddo
+ jj=jas-1
+ do j=jasm,jaem
+ jj=jj+1
+ en_full(iasm,jj,kf,mas)=en_full(iasm+1,jj,kf,mas)
+ en_full(iaem,jj,kf,mas)=en_full(iaem-1,jj,kf,mas)
+ end do
+ enddo
+ enddo
+ deallocate(temp3)
! convert T to Tv: postpone this calculation
! temp3(:,:,:,k3t)=temp3(:,:,:,k3t)*(one+fv*temp3(:,:,:,k3q))
+ allocate(temp2(nlat,nlon,nc2d))
temp2=zero
do k2=1,nc2d
!if(trim(cvars2d(k2))=='sst') then
@@ -844,43 +814,38 @@ subroutine parallel_read_nemsio_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsi
deallocate(work)
if (imp_physics == 11) deallocate(work2)
-! move temp2,temp3 to en_full
- kf=0
- do k3=1,nc3d
- m_cvars3d(k3)=kf+1
- do k=1,nsig
- kf=kf+1
- jj=jas-1
- do j=1,nlon
- jj=jj+1
- ii=ias-1
- do i=1,nlat
- ii=ii+1
- en_full(ii,jj,kf,mas)=temp3(i,j,k,k3)
- enddo
- enddo
- enddo
- enddo
- deallocate(temp3)
+! move temp2 to en_full
do k2=1,nc2d
- m_cvars2d(k2)=kf+1
+ m_cvars2dw(k2)=kf+1
kf=kf+1
- jj=jas-1
+ jj=jas
do j=1,nlon
jj=jj+1
- ii=ias-1
+ ii=ias
do i=1,nlat
ii=ii+1
en_full(ii,jj,kf,mas)=temp2(i,j,k2)
enddo
enddo
+ ii=ias
+ do i=1,nlat
+ ii=ii+1
+ en_full(ii,jasm,kf,mas)=en_full(ii,jaem-1,kf,mas)
+ en_full(ii,jaem,kf,mas)=en_full(ii,jasm+1,kf,mas)
+ enddo
+ jj=jas-1
+ do j=jasm,jaem
+ jj=jj+1
+ en_full(iasm,jj,kf,mas)=en_full(iasm+1,jj,kf,mas)
+ en_full(iaem,jj,kf,mas)=en_full(iaem-1,jj,kf,mas)
+ end do
enddo
deallocate(temp2)
end subroutine parallel_read_nemsio_state_
-subroutine parallel_read_gfsnc_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsig, &
+subroutine parallel_read_gfsnc_state_(en_full,m_cvars2dw,m_cvars3d,nlon,nlat,nsig, &
ias,jas,mas, &
iasm,iaemz,jasm,jaemz,kasm,kaemz,masm,maemz, &
filename)
@@ -894,8 +859,7 @@ subroutine parallel_read_gfsnc_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsig
!
!$$$
- use kinds, only: i_kind,r_kind,r_single
- use constants, only: r60,r3600,zero,one,half,deg2rad
+ use constants, only: r60,r3600,zero,one,half,deg2rad,zero_single
use control_vectors, only: cvars2d,cvars3d,nc2d,nc3d
use general_sub2grid_mod, only: sub2grid_info
use module_ncio, only: Dataset, Variable, Dimension, open_dataset,&
@@ -909,7 +873,7 @@ subroutine parallel_read_gfsnc_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsig
integer(i_kind), intent(in ) :: nlon,nlat,nsig
integer(i_kind), intent(in ) :: ias,jas,mas
integer(i_kind), intent(in ) :: iasm,iaemz,jasm,jaemz,kasm,kaemz,masm,maemz
- integer(i_kind), intent(inout) :: m_cvars2d(nc2d),m_cvars3d(nc3d)
+ integer(i_kind), intent(inout) :: m_cvars2dw(nc2d),m_cvars3d(nc3d)
real(r_single), intent(inout) :: en_full(iasm:iaemz,jasm:jaemz,kasm:kaemz,masm:maemz)
character(len=*), intent(in ) :: filename
@@ -917,7 +881,6 @@ subroutine parallel_read_gfsnc_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsig
logical :: file_exist
integer(i_kind) i,ii,j,jj,k,lonb,latb,levs,kr,ierror
integer(i_kind) k2,k3,k3u,k3v,k3t,k3q,k3cw,k3oz,kf
- integer(i_kind) k3ql,k3qi,k3qr,k3qs,k3qg
character(len=120) :: myname_ = 'parallel_read_gfsnc_state_'
real(r_single),allocatable,dimension(:,:,:) :: rwork3d1, rwork3d2
real(r_single),allocatable,dimension(:,:) :: temp2,rwork2d
@@ -935,12 +898,12 @@ subroutine parallel_read_gfsnc_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsig
call die(myname_, ': ***FATAL ERROR*** insufficient ens fcst for hybrid',999)
endif
+ ierror=0
! If file exists, open and process
atmges = open_dataset(filename,errcode=ierror)
if (ierror /=0) then
- write(6,*)' PARALLEL_READ_GFSNC_STATE: ***FATAL ERROR*** problem reading ',&
- trim(filename),' ierror= ',ierror,' PROGRAM STOPS'
- call die(myname_, ': ***FATAL ERROR*** problem reading ens fcst',999)
+ write(6,*)' PARALLEL_READ_GFSNC_STATE: ***FATAL ERROR*** ',trim(filename),' NOT AVAILABLE: PROGRAM STOPS'
+ call stop2(999)
endif
! get dimension sizes
ncdim = get_dim(atmges, 'grid_xt'); lonb = ncdim%len
@@ -969,9 +932,20 @@ subroutine parallel_read_gfsnc_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsig
allocate(rwork3d1(nlon,(nlat-2),nsig))
allocate(temp3(nlat,nlon,nsig,nc3d))
k3u=0 ; k3v=0 ; k3t=0 ; k3q=0 ; k3cw=0 ; k3oz=0
- k3ql=0; k3qi=0; k3qr=0; k3qs=0; k3qg=0
do k3=1,nc3d
- if (trim(cvars3d(k3))=='cw') then
+ if(trim(cvars3d(k3))=='t') then
+ k3t=k3
+ call read_vardata(atmges, 'tmp', rwork3d1)
+ else if(trim(cvars3d(k3))=='sf') then
+ k3u=k3
+ call read_vardata(atmges, 'ugrd', rwork3d1)
+ else if(trim(cvars3d(k3))=='vp') then
+ k3v=k3
+ call read_vardata(atmges, 'vgrd', rwork3d1)
+ else if(trim(cvars3d(k3))=='q') then
+ k3q=k3
+ call read_vardata(atmges, 'spfh', rwork3d1)
+ else if (trim(cvars3d(k3))=='cw') then
k3cw=k3
call read_vardata(atmges, 'clwmr', rwork3d1)
allocate(rwork3d2(nlon,(nlat-2),nsig))
@@ -979,90 +953,25 @@ subroutine parallel_read_gfsnc_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsig
call read_vardata(atmges, 'icmr', rwork3d2)
rwork3d1 = rwork3d1 + rwork3d2
deallocate(rwork3d2)
- do k=1,nsig
- kr = levs+1-k
- call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- end do
+ else if(trim(cvars3d(k3))=='oz') then
+ k3oz=k3
+ call read_vardata(atmges, 'o3mr', rwork3d1)
else if(trim(cvars3d(k3))=='ql') then
- k3ql=k3
call read_vardata(atmges, 'clwmr', rwork3d1)
- do k=1,nsig
- kr = levs+1-k
- call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- end do
else if(trim(cvars3d(k3))=='qi') then
- k3qi=k3
call read_vardata(atmges, 'icmr', rwork3d1)
- do k=1,nsig
- kr = levs+1-k
- call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- end do
else if(trim(cvars3d(k3))=='qr') then
- k3qr=k3
call read_vardata(atmges, 'rwmr', rwork3d1)
- do k=1,nsig
- kr = levs+1-k
- call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- end do
else if(trim(cvars3d(k3))=='qs') then
- k3qs=k3
call read_vardata(atmges, 'snmr', rwork3d1)
- do k=1,nsig
- kr = levs+1-k
- call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- end do
else if(trim(cvars3d(k3))=='qg') then
- k3qg=k3
call read_vardata(atmges, 'grle', rwork3d1)
- do k=1,nsig
- kr = levs+1-k
- call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- end do
- else if(trim(cvars3d(k3))=='oz') then
- k3oz=k3
- call read_vardata(atmges, 'o3mr', rwork3d1)
- do k=1,nsig
- kr = levs+1-k
- call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- end do
- else if(trim(cvars3d(k3))=='q') then
- k3q=k3
- call read_vardata(atmges, 'spfh', rwork3d1)
- do k=1,nsig
- kr = levs+1-k
- call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- end do
- else if(trim(cvars3d(k3))=='t') then
- k3t=k3
- call read_vardata(atmges, 'tmp', rwork3d1)
- do k=1,nsig
- kr = levs+1-k
- call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
- call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
- end do
- else if(trim(cvars3d(k3))=='sf') then
- k3u=k3
- call read_vardata(atmges, 'ugrd', rwork3d1)
- do k=1,nsig
- kr = levs+1-k
- call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
- end do
- else if(trim(cvars3d(k3))=='vp') then
- k3v=k3
- call read_vardata(atmges, 'vgrd', rwork3d1)
- do k=1,nsig
- kr = levs+1-k
- call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
- end do
end if
+!$omp parallel do schedule(dynamic,1) private(k,kr)
+ do k=1,nsig
+ kr = levs+1-k
+ call move1_(rwork3d1(:,:,kr),temp3(:,:,k,k3),nlon,nlat)
+ end do
enddo
deallocate(rwork3d1)
@@ -1070,52 +979,84 @@ subroutine parallel_read_gfsnc_state_(en_full,m_cvars2d,m_cvars3d,nlon,nlat,nsig
if (k3u==0.or.k3v==0.or.k3t==0.or.k3q==0.or.k3oz==0) &
write(6,'(" WARNING, problem with one of k3-")')
+!$omp parallel do schedule(dynamic,1) private(k,k3)
do k=1,nsig
call fillpoles_sv_(temp3(:,:,k,k3u),temp3(:,:,k,k3v),nlon,nlat,clons,slons)
end do
-! move temp2,temp3 to en_full
- kf=0
+! move temp3 to en_full
+!$omp parallel do schedule(dynamic,1) private(k3,k,kf,j,jj,i,ii)
do k3=1,nc3d
+ if(k3 /= k3u .and. k3 /= k3v)then
+ do k=1,nsig
+ call fillpoles_ss_(temp3(:,:,k,k3),nlon,nlat)
+ end do
+ end if
+ kf=(k3-1)*nsig
m_cvars3d(k3)=kf+1
do k=1,nsig
kf=kf+1
- jj=jas-1
+ jj=jas
do j=1,nlon
jj=jj+1
- ii=ias-1
+ ii=ias
do i=1,nlat
ii=ii+1
en_full(ii,jj,kf,mas)=temp3(i,j,k,k3)
enddo
enddo
+ ii=ias
+ do i=1,nlat
+ ii=ii+1
+ en_full(ii,jasm,kf,mas)=en_full(ii,jaem-1,kf,mas)
+ en_full(ii,jaem,kf,mas)=en_full(ii,jasm+1,kf,mas)
+ enddo
+ jj=jas-1
+ do j=jasm,jaem
+ jj=jj+1
+ en_full(iasm,jj,kf,mas)=en_full(iasm+1,jj,kf,mas)
+ en_full(iaem,jj,kf,mas)=en_full(iaem-1,jj,kf,mas)
+ end do
enddo
enddo
deallocate(temp3)
allocate(temp2(nlat,nlon))
allocate(rwork2d(nlon,(nlat-2)))
+ kf=nc3d*nsig
do k2=1,nc2d
if(trim(cvars2d(k2))=='ps') then
call read_vardata(atmges, 'pressfc', rwork2d)
call move1_(rwork2d,temp2,nlon,nlat)
call fillpoles_ss_(temp2,nlon,nlat)
- else
- temp2=zero
- endif
- kf=kf+1
- m_cvars2d(k2)=kf
- jj=jas-1
- do j=1,nlon
- jj=jj+1
- ii=ias-1
+! move temp2 to en_full
+ kf=kf+1
+ m_cvars2dw(k2)=kf
+ jj=jas
+ do j=1,nlon
+ jj=jj+1
+ ii=ias
+ do i=1,nlat
+ ii=ii+1
+ en_full(ii,jj,kf,mas)=temp2(i,j)
+ enddo
+ enddo
+ ii=ias
do i=1,nlat
ii=ii+1
- en_full(ii,jj,kf,mas)=temp2(i,j)
+ en_full(ii,jasm,kf,mas)=en_full(ii,jaem-1,kf,mas)
+ en_full(ii,jaem,kf,mas)=en_full(ii,jasm+1,kf,mas)
enddo
- enddo
+ jj=jas-1
+ do j=jasm,jaem
+ jj=jj+1
+ en_full(iasm,jj,kf,mas)=en_full(iasm+1,jj,kf,mas)
+ en_full(iaem,jj,kf,mas)=en_full(iaem-1,jj,kf,mas)
+ end do
+ end if
enddo
+ call close_dataset(atmges)
deallocate(rwork2d)
deallocate(temp2)
@@ -1148,7 +1089,6 @@ subroutine fillpoles_ss_(temp,nlon,nlat)
!
!$$$
- use kinds, only: i_kind,r_kind,r_single
use constants, only: zero,one
implicit none
@@ -1158,6 +1098,7 @@ subroutine fillpoles_ss_(temp,nlon,nlat)
integer(i_kind) nlatm1,i
real(r_kind) sumn,sums,rnlon
+ real(r_single) sumn_sing,sums_sing
! Compute mean along southern and northern latitudes
sumn=zero
@@ -1167,14 +1108,14 @@ subroutine fillpoles_ss_(temp,nlon,nlat)
sumn=sumn+temp(nlatm1,i)
sums=sums+temp(2,i)
end do
- rnlon=one/float(nlon)
- sumn=sumn*rnlon
- sums=sums*rnlon
+ rnlon=one/real(nlon,r_kind)
+ sumn_sing=sumn*rnlon
+ sums_sing=sums*rnlon
! Load means into local work array
do i=1,nlon
- temp(1,i) =sums
- temp(nlat,i)=sumn
+ temp(1,i) =sums_sing
+ temp(nlat,i)=sumn_sing
end do
end subroutine fillpoles_ss_
@@ -1206,16 +1147,15 @@ subroutine fillpoles_sv_(tempu,tempv,nlon,nlat,clons,slons)
!
!$$$
- use kinds, only: i_kind,r_kind,r_single
use constants, only: zero
implicit none
integer(i_kind),intent(in ) :: nlon,nlat
- real(r_single), intent(inout) :: tempu(nlat,nlon),tempv(nlat,nlon)
+ real(r_single), intent(inout) :: tempu(nlat,nlon),tempv(nlat,nlon)
real(r_kind), intent(in ) :: clons(nlon),slons(nlon)
- integer(i_kind) i
+ integer(i_kind) i,nlatm
real(r_kind) polnu,polnv,polsu,polsv
! Compute mean along southern and northern latitudes
@@ -1223,16 +1163,17 @@ subroutine fillpoles_sv_(tempu,tempv,nlon,nlat,clons,slons)
polnv=zero
polsu=zero
polsv=zero
+ nlatm=nlat-1
do i=1,nlon
- polnu=polnu+tempu(nlat-1,i)*clons(i)-tempv(nlat-1,i)*slons(i)
- polnv=polnv+tempu(nlat-1,i)*slons(i)+tempv(nlat-1,i)*clons(i)
- polsu=polsu+tempu(2,i )*clons(i)+tempv(2,i )*slons(i)
- polsv=polsv+tempu(2,i )*slons(i)-tempv(2,i )*clons(i)
+ polnu=polnu+tempu(nlatm,i)*clons(i)-tempv(nlatm,i)*slons(i)
+ polnv=polnv+tempu(nlatm,i)*slons(i)+tempv(nlatm,i)*clons(i)
+ polsu=polsu+tempu(2,i )*clons(i)+tempv(2,i )*slons(i)
+ polsv=polsv+tempu(2,i )*slons(i)-tempv(2,i )*clons(i)
end do
- polnu=polnu/float(nlon)
- polnv=polnv/float(nlon)
- polsu=polsu/float(nlon)
- polsv=polsv/float(nlon)
+ polnu=polnu/real(nlon,r_kind)
+ polnv=polnv/real(nlon,r_kind)
+ polsu=polsu/real(nlon,r_kind)
+ polsv=polsv/real(nlon,r_kind)
do i=1,nlon
tempu(nlat,i)= polnu*clons(i)+polnv*slons(i)
tempv(nlat,i)=-polnu*slons(i)+polnv*clons(i)
@@ -1267,7 +1208,6 @@ subroutine move1_(work,temp,nlon,nlat)
!
!$$$
- use kinds, only: i_kind,r_kind,r_single
use constants, only: zero
implicit none
@@ -1317,7 +1257,6 @@ subroutine get_gfs_ens(this,grd,member,ntindex,atm_bundle,iret)
!
!$$$
- use kinds, only: i_kind,r_kind
use gridmod, only: use_gfs_nemsio, use_gfs_ncio
use general_sub2grid_mod, only: sub2grid_info
use gsi_4dvar, only: ens_fhrlevs
@@ -1421,7 +1360,6 @@ subroutine put_gfs_ens(this,grd,member,ntindex,pert,iret)
!
!$$$
- use kinds, only: i_kind
use general_sub2grid_mod, only: sub2grid_info
use gsi_bundlemod, only: gsi_bundle
use gsi_4dvar, only: ens_fhrlevs
@@ -1484,7 +1422,6 @@ end subroutine put_gfs_ens
subroutine non_gaussian_ens_grid_gfs(this,elats,elons)
- use kinds, only: r_kind
use hybrid_ensemble_parameters, only: sp_ens
implicit none
@@ -1516,7 +1453,6 @@ end subroutine non_gaussian_ens_grid_gfs
subroutine create_sub2grid_info(s2gi,nsig,npe,s2gi_ref)
!> Create temporary communication information object for read ensemble routines
- use kinds, only: i_kind
use gridmod, only: regional
use general_sub2grid_mod, only: sub2grid_info
use general_sub2grid_mod, only: general_sub2grid_create_info
diff --git a/src/gsi/cplr_gfs_nstmod.f90 b/src/gsi/cplr_gfs_nstmod.f90
index b482085aac..220fa55af1 100644
--- a/src/gsi/cplr_gfs_nstmod.f90
+++ b/src/gsi/cplr_gfs_nstmod.f90
@@ -139,15 +139,15 @@ subroutine deter_nst_(dlat_earth,dlon_earth,obstime,zob,tref,dtw,dtc,tz_tr)
integer(i_kind):: itnst,itnstp
integer(i_kind):: ix,iy,ixp,iyp,j
real(r_kind):: dx,dy,dx1,dy1,w00,w10,w01,w11,dtnst,dtnstp
- real(r_kind):: tref_00,tref_01,tref_10,tref_11,tr_tmp
- real(r_kind):: dt_cool_00,dt_cool_01,dt_cool_10,dt_cool_11
- real(r_kind):: z_c_00,z_c_01,z_c_10,z_c_11
- real(r_kind):: dt_warm_00,dt_warm_01,dt_warm_10,dt_warm_11
- real(r_kind):: z_w_00,z_w_01,z_w_10,z_w_11,z_w_tmp
- real(r_kind):: c_0_00,c_0_01,c_0_10,c_0_11
- real(r_kind):: c_d_00,c_d_01,c_d_10,c_d_11
- real(r_kind):: w_0_00,w_0_01,w_0_10,w_0_11
- real(r_kind):: w_d_00,w_d_01,w_d_10,w_d_11
+ real(r_kind):: tref_tt,tref2
+ real(r_kind):: dt_cool_tt
+ real(r_kind):: z_c_tt
+ real(r_kind):: dt_warm_tt
+ real(r_kind):: z_w_tt
+ real(r_kind):: c_0_tt
+ real(r_kind):: c_d_tt
+ real(r_kind):: w_0_tt
+ real(r_kind):: w_d_tt
real(r_kind):: wgtavg,dlat,dlon
logical outside
@@ -199,138 +199,137 @@ subroutine deter_nst_(dlat_earth,dlon_earth,obstime,zob,tref,dtw,dtc,tz_tr)
!
! Use the time interpolation factors for nst files
!
- tref_00 = tref_full (ix ,iy ,itnst)*dtnst + tref_full (ix ,iy ,itnstp)*dtnstp
- tref_01 = tref_full (ix ,iyp,itnst)*dtnst + tref_full (ix ,iyp,itnstp)*dtnstp
- tref_10 = tref_full (ixp,iy ,itnst)*dtnst + tref_full (ixp,iy ,itnstp)*dtnstp
- tref_11 = tref_full (ixp,iyp,itnst)*dtnst + tref_full (ixp,iyp,itnstp)*dtnstp
-
- dt_cool_00 = dt_cool_full(ix ,iy ,itnst)*dtnst + dt_cool_full(ix ,iy ,itnstp)*dtnstp
- dt_cool_01 = dt_cool_full(ix ,iyp,itnst)*dtnst + dt_cool_full(ix ,iyp,itnstp)*dtnstp
- dt_cool_10 = dt_cool_full(ixp,iy ,itnst)*dtnst + dt_cool_full(ixp,iy ,itnstp)*dtnstp
- dt_cool_11 = dt_cool_full(ixp,iyp,itnst)*dtnst + dt_cool_full(ixp,iyp,itnstp)*dtnstp
-
- z_c_00 = z_c_full (ix ,iy ,itnst)*dtnst + z_c_full (ix ,iy ,itnstp)*dtnstp
- z_c_01 = z_c_full (ix ,iyp,itnst)*dtnst + z_c_full (ix ,iyp,itnstp)*dtnstp
- z_c_10 = z_c_full (ixp,iy ,itnst)*dtnst + z_c_full (ixp,iy ,itnstp)*dtnstp
- z_c_11 = z_c_full (ixp,iyp,itnst)*dtnst + z_c_full (ixp,iyp,itnstp)*dtnstp
-
- dt_warm_00 = dt_warm_full(ix ,iy ,itnst)*dtnst + dt_warm_full(ix ,iy ,itnstp)*dtnstp
- dt_warm_01 = dt_warm_full(ix ,iyp,itnst)*dtnst + dt_warm_full(ix ,iyp,itnstp)*dtnstp
- dt_warm_10 = dt_warm_full(ixp,iy ,itnst)*dtnst + dt_warm_full(ixp,iy ,itnstp)*dtnstp
- dt_warm_11 = dt_warm_full(ixp,iyp,itnst)*dtnst + dt_warm_full(ixp,iyp,itnstp)*dtnstp
-
- z_w_00 = z_w_full (ix ,iy ,itnst)*dtnst + z_w_full (ix ,iy ,itnstp)*dtnstp
- z_w_01 = z_w_full (ix ,iyp,itnst)*dtnst + z_w_full (ix ,iyp,itnstp)*dtnstp
- z_w_10 = z_w_full (ixp,iy ,itnst)*dtnst + z_w_full (ixp,iy ,itnstp)*dtnstp
- z_w_11 = z_w_full (ixp,iyp,itnst)*dtnst + z_w_full (ixp,iyp,itnstp)*dtnstp
-
- c_0_00 = c_0_full (ix ,iy ,itnst)*dtnst + c_0_full (ix ,iy ,itnstp)*dtnstp
- c_0_01 = c_0_full (ix ,iyp,itnst)*dtnst + c_0_full (ix ,iyp,itnstp)*dtnstp
- c_0_10 = c_0_full (ixp,iy ,itnst)*dtnst + c_0_full (ixp,iy ,itnstp)*dtnstp
- c_0_11 = c_0_full (ixp,iyp,itnst)*dtnst + c_0_full (ixp,iyp,itnstp)*dtnstp
-
- c_d_00 = c_d_full (ix ,iy ,itnst)*dtnst + c_d_full (ix ,iy ,itnstp)*dtnstp
- c_d_01 = c_d_full (ix ,iyp,itnst)*dtnst + c_d_full (ix ,iyp,itnstp)*dtnstp
- c_d_10 = c_d_full (ixp,iy ,itnst)*dtnst + c_d_full (ixp,iy ,itnstp)*dtnstp
- c_d_11 = c_d_full (ixp,iyp,itnst)*dtnst + c_d_full (ixp,iyp,itnstp)*dtnstp
-
- w_0_00 = w_0_full (ix ,iy ,itnst)*dtnst + w_0_full (ix ,iy ,itnstp)*dtnstp
- w_0_01 = w_0_full (ix ,iyp,itnst)*dtnst + w_0_full (ix ,iyp,itnstp)*dtnstp
- w_0_10 = w_0_full (ixp,iy ,itnst)*dtnst + w_0_full (ixp,iy ,itnstp)*dtnstp
- w_0_11 = w_0_full (ixp,iyp,itnst)*dtnst + w_0_full (ixp,iyp,itnstp)*dtnstp
-
- w_d_00 = w_d_full (ix ,iy ,itnst)*dtnst + w_d_full (ix ,iy ,itnstp)*dtnstp
- w_d_01 = w_d_full (ix ,iyp,itnst)*dtnst + w_d_full (ix ,iyp,itnstp)*dtnstp
- w_d_10 = w_d_full (ixp,iy ,itnst)*dtnst + w_d_full (ixp,iy ,itnstp)*dtnstp
- w_d_11 = w_d_full (ixp,iyp,itnst)*dtnst + w_d_full (ixp,iyp,itnstp)*dtnstp
! Interpolate nst variables to obs location (water surface only)
wgtavg = zero
- tr_tmp = zero
+ tref2 = zero
dt_cool = zero
- z_c = zero
dt_warm = zero
- z_w_tmp = zero
+ z_c = zero
+ z_w = zero
c_0 = zero
c_d = zero
w_0 = zero
w_d = zero
+ tz_tr = one
+ dtw = zero
+ dtc = zero
if (istyp00 == 0)then
+ tref_tt = tref_full (ix ,iy ,itnst)*dtnst + tref_full (ix ,iy ,itnstp)*dtnstp
+ dt_cool_tt = dt_cool_full(ix ,iy ,itnst)*dtnst + dt_cool_full(ix ,iy ,itnstp)*dtnstp
+ dt_warm_tt = dt_warm_full(ix ,iy ,itnst)*dtnst + dt_warm_full(ix ,iy ,itnstp)*dtnstp
+ z_c_tt = z_c_full (ix ,iy ,itnst)*dtnst + z_c_full (ix ,iy ,itnstp)*dtnstp
+ z_w_tt = z_w_full (ix ,iy ,itnst)*dtnst + z_w_full (ix ,iy ,itnstp)*dtnstp
+ c_0_tt = c_0_full (ix ,iy ,itnst)*dtnst + c_0_full (ix ,iy ,itnstp)*dtnstp
+ c_d_tt = c_d_full (ix ,iy ,itnst)*dtnst + c_d_full (ix ,iy ,itnstp)*dtnstp
+ w_0_tt = w_0_full (ix ,iy ,itnst)*dtnst + w_0_full (ix ,iy ,itnstp)*dtnstp
+ w_d_tt = w_d_full (ix ,iy ,itnst)*dtnst + w_d_full (ix ,iy ,itnstp)*dtnstp
wgtavg = wgtavg + w00
- tr_tmp = tr_tmp + w00*tref_00
- dt_cool = dt_cool + w00*dt_cool_00
- z_c = z_c + w00*z_c_00
- dt_warm = dt_warm + w00*dt_warm_00
- z_w_tmp = z_w_tmp + w00*z_w_00
- c_0 = c_0 + w00*c_0_00
- c_d = c_d + w00*c_d_00
- w_0 = w_0 + w00*w_0_00
- w_d = w_d + w00*w_d_00
+ tref2 = tref2 + w00*tref_tt
+ dt_cool = dt_cool + w00*dt_cool_tt
+ dt_warm = dt_warm + w00*dt_warm_tt
+ z_c = z_c + w00*z_c_tt
+ z_w = z_w + w00*z_w_tt
+ c_0 = c_0 + w00*c_0_tt
+ c_d = c_d + w00*c_d_tt
+ w_0 = w_0 + w00*w_0_tt
+ w_d = w_d + w00*w_d_tt
endif
if(istyp01 == 0)then
+ tref_tt = tref_full (ix ,iyp,itnst)*dtnst + tref_full (ix ,iyp,itnstp)*dtnstp
+ dt_cool_tt = dt_cool_full(ix ,iyp,itnst)*dtnst + dt_cool_full(ix ,iyp,itnstp)*dtnstp
+ dt_warm_tt = dt_warm_full(ix ,iyp,itnst)*dtnst + dt_warm_full(ix ,iyp,itnstp)*dtnstp
+ z_c_tt = z_c_full (ix ,iyp,itnst)*dtnst + z_c_full (ix ,iyp,itnstp)*dtnstp
+ z_w_tt = z_w_full (ix ,iyp,itnst)*dtnst + z_w_full (ix ,iyp,itnstp)*dtnstp
+ c_0_tt = c_0_full (ix ,iyp,itnst)*dtnst + c_0_full (ix ,iyp,itnstp)*dtnstp
+ c_d_tt = c_d_full (ix ,iyp,itnst)*dtnst + c_d_full (ix ,iyp,itnstp)*dtnstp
+ w_0_tt = w_0_full (ix ,iyp,itnst)*dtnst + w_0_full (ix ,iyp,itnstp)*dtnstp
+ w_d_tt = w_d_full (ix ,iyp,itnst)*dtnst + w_d_full (ix ,iyp,itnstp)*dtnstp
wgtavg = wgtavg + w01
- tr_tmp = tr_tmp + w01*tref_01
- dt_cool = dt_cool + w01*dt_cool_01
- z_c = z_c + w01*z_c_01
- dt_warm = dt_warm + w01*dt_warm_01
- z_w_tmp = z_w_tmp + w01*z_w_01
- c_0 = c_0 + w01*c_0_01
- c_d = c_d + w01*c_d_01
- w_0 = w_0 + w01*w_0_01
- w_d = w_d + w01*w_d_01
+ tref2 = tref2 + w01*tref_tt
+ dt_cool = dt_cool + w01*dt_cool_tt
+ dt_warm = dt_warm + w01*dt_warm_tt
+ z_c = z_c + w01*z_c_tt
+ z_w = z_w + w01*z_w_tt
+ c_0 = c_0 + w01*c_0_tt
+ c_d = c_d + w01*c_d_tt
+ w_0 = w_0 + w01*w_0_tt
+ w_d = w_d + w01*w_d_tt
end if
if(istyp10 == 0)then
+ tref_tt = tref_full (ixp,iy ,itnst)*dtnst + tref_full (ixp,iy ,itnstp)*dtnstp
+ dt_cool_tt = dt_cool_full(ixp,iy ,itnst)*dtnst + dt_cool_full(ixp,iy ,itnstp)*dtnstp
+ dt_warm_tt = dt_warm_full(ixp,iy ,itnst)*dtnst + dt_warm_full(ixp,iy ,itnstp)*dtnstp
+ z_c_tt = z_c_full (ixp,iy ,itnst)*dtnst + z_c_full (ixp,iy ,itnstp)*dtnstp
+ z_w_tt = z_w_full (ixp,iy ,itnst)*dtnst + z_w_full (ixp,iy ,itnstp)*dtnstp
+ c_0_tt = c_0_full (ixp,iy ,itnst)*dtnst + c_0_full (ixp,iy ,itnstp)*dtnstp
+ c_d_tt = c_d_full (ixp,iy ,itnst)*dtnst + c_d_full (ixp,iy ,itnstp)*dtnstp
+ w_0_tt = w_0_full (ixp,iy ,itnst)*dtnst + w_0_full (ixp,iy ,itnstp)*dtnstp
+ w_d_tt = w_d_full (ixp,iy ,itnst)*dtnst + w_d_full (ixp,iy ,itnstp)*dtnstp
wgtavg = wgtavg + w10
- tr_tmp = tr_tmp + w10*tref_10
- dt_cool = dt_cool + w10*dt_cool_10
- z_c = z_c + w10*z_c_10
- dt_warm = dt_warm + w10*dt_warm_10
- z_w_tmp = z_w_tmp + w10*z_w_10
- c_0 = c_0 + w10*c_0_10
- c_d = c_d + w10*c_d_10
- w_0 = w_0 + w10*w_0_10
- w_d = w_d + w10*w_d_10
+ tref2 = tref2 + w10*tref_tt
+ dt_cool = dt_cool + w10*dt_cool_tt
+ dt_warm = dt_warm + w10*dt_warm_tt
+ z_c = z_c + w10*z_c_tt
+ z_w = z_w + w10*z_w_tt
+ c_0 = c_0 + w10*c_0_tt
+ c_d = c_d + w10*c_d_tt
+ w_0 = w_0 + w10*w_0_tt
+ w_d = w_d + w10*w_d_tt
end if
if(istyp11 == 0)then
+ tref_tt = tref_full (ixp,iyp,itnst)*dtnst + tref_full (ixp,iyp,itnstp)*dtnstp
+ dt_cool_tt = dt_cool_full(ixp,iyp,itnst)*dtnst + dt_cool_full(ixp,iyp,itnstp)*dtnstp
+ dt_warm_tt = dt_warm_full(ixp,iyp,itnst)*dtnst + dt_warm_full(ixp,iyp,itnstp)*dtnstp
+ z_c_tt = z_c_full (ixp,iyp,itnst)*dtnst + z_c_full (ixp,iyp,itnstp)*dtnstp
+ z_w_tt = z_w_full (ixp,iyp,itnst)*dtnst + z_w_full (ixp,iyp,itnstp)*dtnstp
+ c_0_tt = c_0_full (ixp,iyp,itnst)*dtnst + c_0_full (ixp,iyp,itnstp)*dtnstp
+ c_d_tt = c_d_full (ixp,iyp,itnst)*dtnst + c_d_full (ixp,iyp,itnstp)*dtnstp
+ w_0_tt = w_0_full (ixp,iyp,itnst)*dtnst + w_0_full (ixp,iyp,itnstp)*dtnstp
+ w_d_tt = w_d_full (ixp,iyp,itnst)*dtnst + w_d_full (ixp,iyp,itnstp)*dtnstp
wgtavg = wgtavg + w11
- tr_tmp = tr_tmp + w11*tref_11
- dt_cool = dt_cool + w11*dt_cool_11
- z_c = z_c + w11*z_c_11
- dt_warm = dt_warm + w11*dt_warm_11
- z_w_tmp = z_w_tmp + w11*z_w_11
- c_0 = c_0 + w11*c_0_11
- c_d = c_d + w11*c_d_11
- w_0 = w_0 + w11*w_0_11
- w_d = w_d + w11*w_d_11
+ tref2 = tref2 + w11*tref_tt
+ dt_cool = dt_cool + w11*dt_cool_tt
+ dt_warm = dt_warm + w11*dt_warm_tt
+ z_c = z_c + w11*z_c_tt
+ z_w = z_w + w11*z_w_tt
+ c_0 = c_0 + w11*c_0_tt
+ c_d = c_d + w11*c_d_tt
+ w_0 = w_0 + w11*w_0_tt
+ w_d = w_d + w11*w_d_tt
end if
+ if(wgtavg < 1.e-6)return
- if(wgtavg > zero)then
- tr_tmp = tr_tmp/wgtavg
- tref = tr_tmp
-
- z_w_tmp = z_w_tmp/wgtavg
- z_w = z_w_tmp
+ tref = tref2/wgtavg
+ z_w = z_w/wgtavg
+ z_c = z_c/wgtavg
- dt_cool = dt_cool/wgtavg
- z_c = z_c/wgtavg
- dt_warm = dt_warm/wgtavg
+ if(fac_tsl == 1)then
c_0 = c_0/wgtavg
c_d = c_d/wgtavg
+ dt_cool = dt_cool/wgtavg
+ if(z_c > zero)dtc = dt_cool*(one-min(zob,z_c)/z_c)
+ else
+ c_0 = zero
+ c_d = zero
+ dt_cool = zero
+ end if
+ if(fac_dtl == 1)then
w_0 = w_0/wgtavg
w_d = w_d/wgtavg
+ dt_warm = dt_warm/wgtavg
+ if(z_w > zero)dtw = dt_warm*(one-min(zob,z_w)/z_w)
+ else
+ w_0 = zero
+ w_d = zero
+ dt_warm = zero
+ end if
- dtw = fac_dtl*dt_warm*(one-min(zob,z_w)/z_w)
- if ( z_c > zero ) then
- dtc = fac_tsl*dt_cool*(one-min(zob,z_c)/z_c)
- else
- dtc = zero
- endif
- call cal_tztr_(dt_warm,c_0,c_d,w_0,w_d,z_c,z_w,zob,tz_tr)
+ call cal_tztr_(dt_warm,c_0,c_d,w_0,w_d,z_c,z_w,zob,tz_tr)
- end if
end subroutine deter_nst_
!*******************************************************************************************
@@ -343,10 +342,10 @@ subroutine cal_tztr_(dt_warm,c_0,c_d,w_0,w_d,zc,zw,z,tztr)
!
! dt_warm : diurnal warming amount at the surface
! xz : DTL depth (M)
-! c_0 : coefficint 1 to calculate d(Tc)/d(Ts)
-! c_d : coefficint 2 to calculate d(Tc)/d(Ts)
-! w_0 : coefficint 1 to calculate d(Tw)/d(Ts)
-! w_d : coefficint 2 to calculate d(Tw)/d(Ts)
+! c_0 : coefficient 1 to calculate d(Tc)/d(Ts)
+! c_d : coefficient 2 to calculate d(Tc)/d(Ts)
+! w_0 : coefficient 1 to calculate d(Tw)/d(Ts)
+! w_d : coefficient 2 to calculate d(Tw)/d(Ts)
!
! output variables
!
@@ -354,34 +353,39 @@ subroutine cal_tztr_(dt_warm,c_0,c_d,w_0,w_d,zc,zw,z,tztr)
use kinds, only: r_kind
use constants, only: one,two,half,zero
- use gsi_nstcouplermod, only: fac_dtl,fac_tsl
real(kind=r_kind), intent(in) :: dt_warm,c_0,c_d,w_0,w_d,zc,zw,z
real(kind=r_kind), intent(out) :: tztr
! local variables
- real(kind=r_kind) :: c1,c2,c3
+ real(kind=r_kind) :: c1,c2,c3,fact
- c1 = one-two*(fac_dtl*w_0-fac_tsl*c_0)-(fac_dtl*w_d-fac_tsl*c_d)*z
- c2 = one-two*(fac_dtl*w_0-fac_tsl*c_0)-fac_dtl*w_d*z
- c3 = one+fac_tsl*two*c_0+fac_dtl*c_d*z
tztr = one
+ c1 = zero
+ c2 = zero
+ c3 = zero
if ( dt_warm > zero ) then
- if ( z <= zc .and. c1 /= zero ) then
- tztr = (one-fac_dtl*w_0+fac_tsl*c_0)/c1
- elseif ( z > zc .and. z < zw .and. c2 /= zero ) then
- tztr = (one-fac_dtl*w_0+fac_tsl*c_0)/c2
+ fact = (one-w_0+c_0)
+ if ( z <= zc) then
+ c1 = one-two*(w_0-c_0)-(w_d-c_d)*z
+ if ( c1 /= zero ) tztr = fact/c1
+ elseif ( z > zc .and. z < zw) then
+ c2 = one-two*(w_0-c_0)-w_d*z
+ if (c2 /= zero ) tztr = fact/c2
+ else
endif
- elseif ( dt_warm == zero .and. c3 /= zero ) then
- if ( z <= zc ) then
- tztr = (one+fac_tsl*c_0)/c3
+ elseif (dt_warm == zero) then
+ if ( z <= zc) then
+ c3 = one+two*c_0+c_d*z
+ if (c3 /= zero) tztr = (one+c_0)/c3
endif
endif
- if ( tztr <= -1.0_r_kind .or. tztr > 4.0_r_kind ) then
- write(6,100) fac_dtl,fac_tsl,c1,c2,c3,dt_warm,c_0,c_d,w_0,w_d,zc,zw,z,tztr
-100 format('CAL_TZTR compute ',2(i2,1x),12(g13.6,1x),' RESET tztr to 1.0')
- tztr = one
+ if ( tztr < 0.5_r_kind .or. tztr > 1.5_r_kind ) then
+ write(6,100) c1,c2,c3,dt_warm,c_0,c_d,w_0,w_d,zc,zw,z,tztr
+100 format('CAL_TZTR compute ',12(g13.6,1x),' RESET tztr to 0.5 .or. 1.5')
+ tztr = min(1.5_r_kind,tztr)
+ tztr = max(0.5_r_kind,tztr)
endif
end subroutine cal_tztr_
diff --git a/src/gsi/cplr_read_wrf_nmm_guess.f90 b/src/gsi/cplr_read_wrf_nmm_guess.f90
index 63b1bac54a..cc1ecf5528 100644
--- a/src/gsi/cplr_read_wrf_nmm_guess.f90
+++ b/src/gsi/cplr_read_wrf_nmm_guess.f90
@@ -2077,7 +2077,7 @@ subroutine read_nems_nmmb_guess_wrf(this,mype)
! due to interpolation
do i=1,lon2
do j=1,lat2
- veg_type(j,i,it)=float(nint(veg_type(j,i,it)))
+ veg_type(j,i,it)=real(nint(veg_type(j,i,it)),r_kind)
end do
end do
! ! veg frac
@@ -2091,7 +2091,7 @@ subroutine read_nems_nmmb_guess_wrf(this,mype)
! due to interpolation
do i=1,lon2
do j=1,lat2
- soil_type(j,i,it)=float(nint(soil_type(j,i,it)))
+ soil_type(j,i,it)=real(nint(soil_type(j,i,it)),r_kind)
end do
end do
@@ -2102,7 +2102,7 @@ subroutine read_nems_nmmb_guess_wrf(this,mype)
! due to interpolation
do i=1,lon2
do j=1,lat2
- smthis(j,i)=float(nint(smthis(j,i)))
+ smthis(j,i)=real(nint(smthis(j,i)),r_kind)
end do
end do
@@ -2113,7 +2113,7 @@ subroutine read_nems_nmmb_guess_wrf(this,mype)
! due to interpolation
do i=1,lon2
do j=1,lat2
- sicethis(j,i)=float(nint(sicethis(j,i)))
+ sicethis(j,i)=real(nint(sicethis(j,i)),r_kind)
end do
end do
diff --git a/src/gsi/cplr_wrf_netcdf_interface.f90 b/src/gsi/cplr_wrf_netcdf_interface.f90
index 5739b27b73..7c1bc400ec 100644
--- a/src/gsi/cplr_wrf_netcdf_interface.f90
+++ b/src/gsi/cplr_wrf_netcdf_interface.f90
@@ -3388,7 +3388,7 @@ subroutine update_netcdf_mass_wrf(this)
myname_,'put_att: START_DATE '//trim(flnm1) )
call nc_check( nf90_put_att(dh1,nf90_global,'SIMULATION_START_DATE',trim(DateStr1)),&
myname_,'put_att: SIMULATION_START_DATE '//trim(flnm1) )
- call nc_check( nf90_put_att(dh1,nf90_global,'GMT',float(ihour)),&
+ call nc_check( nf90_put_att(dh1,nf90_global,'GMT',real(ihour,r_single)),&
myname_,'put_att: GMT '//trim(flnm1) )
call nc_check( nf90_put_att(dh1,nf90_global,'JULYR',iyear),&
myname_,'put_att: JULYR'//trim(flnm1) )
@@ -3885,7 +3885,7 @@ subroutine update_netcdf_nmm_wrf(this)
myname_,'put_att: START_DATE '//trim(adjustl(flnm1)) )
call nc_check( nf90_put_att(dh1,nf90_global,'SIMULATION_START_DATE',trim(DateStr1)),&
myname_,'put_att: SIMULATION_START_DATE '//trim(adjustl(flnm1)) )
- call nc_check( nf90_put_att(dh1,nf90_global,'GMT',float(ihour)),&
+ call nc_check( nf90_put_att(dh1,nf90_global,'GMT',real(ihour,r_single)),&
myname_,'put_att: GMT '//trim(adjustl(flnm1)) )
call nc_check( nf90_put_att(dh1,nf90_global,'JULYR',iyear),&
myname_,'put_att: JULYR'//trim(adjustl(flnm1)) )
diff --git a/src/gsi/crtm_interface.f90 b/src/gsi/crtm_interface.f90
index 2305c84340..3f06daa315 100644
--- a/src/gsi/crtm_interface.f90
+++ b/src/gsi/crtm_interface.f90
@@ -85,6 +85,7 @@ module crtm_interface
public destroy_crtm ! Subroutine destroys initialization for crtm
public sensorindex
public surface
+public atmosphere
public isatid ! = 1 index of satellite id
public itime ! = 2 index of analysis relative obs time
public ilon ! = 3 index of grid relative obs location (x)
@@ -125,6 +126,8 @@ module crtm_interface
public idtw ! = 35/37 index of d(Tw)
public idtc ! = 36/38 index of d(Tc)
public itz_tr ! = 37/39 index of d(Tz)/d(Tr)
+public n_clouds_fwd_wk
+public n_absorbers
! For TMI and GMI
public iedge_log ! = 32 ! index, if obs is to be obleted beause of locating near scan edges.
@@ -202,6 +205,7 @@ module crtm_interface
logical ,save :: mixed_use
logical ,save :: use_gfdl_qsat
integer(i_kind), parameter :: min_n_absorbers = 2
+ integer(i_kind) :: n_absorbers
integer(i_kind),save :: iedge_log
integer(i_kind),save :: ilzen_ang2,ilazi_ang2,iscan_ang2,iszen_ang2,isazi_ang2
@@ -356,7 +360,6 @@ subroutine init_crtm(init_pass,mype_diaghdr,mype,nchanl,nreal,isis,obstype,radmo
! ...all "additional absorber" variables
integer(i_kind) :: j,icount
integer(i_kind) :: ig
- integer(i_kind) :: n_absorbers
logical quiet
logical print_verbose
@@ -977,7 +980,7 @@ end subroutine destroy_crtm
subroutine call_crtm(obstype,obstime,data_s,nchanl,nreal,ich, &
h,q,qs,clw_guess,ciw_guess,rain_guess,snow_guess,prsl,prsi, &
trop5,tzbgr,dtsavg,sfc_speed,&
- tsim,emissivity,ptau5,ts, &
+ tsim,emissivity,chan_level,ptau5,ts, &
emissivity_k,temp,wmix,jacobian,error_status,tsim_clr,tcc, &
tcwv,hwp_ratio,stability,layer_od,jacobian_aero)
!$$$ subprogram documentation block
@@ -1097,6 +1100,7 @@ subroutine call_crtm(obstype,obstime,data_s,nchanl,nreal,ich, &
real(r_kind) ,intent( out) :: sfc_speed,dtsavg
real(r_kind),dimension(nchanl+nreal) ,intent(in ) :: data_s
real(r_kind),dimension(nchanl) ,intent( out) :: tsim,emissivity,ts,emissivity_k
+ real(r_kind),dimension(nchanl) ,intent( out) :: chan_level
character(10) ,intent(in ) :: obstype
integer(i_kind) ,intent( out) :: error_status
real(r_kind),dimension(nsig,nchanl) ,intent( out) :: temp,ptau5,wmix
@@ -1150,6 +1154,7 @@ subroutine call_crtm(obstype,obstime,data_s,nchanl,nreal,ich, &
real(r_kind):: sno00,sno01,sno10,sno11,secant_term
real(r_kind):: hwp_total,theta_700,theta_sfc,hs
real(r_kind):: dlon,dlat,dxx,dyy,yy,zz,garea
+ real(r_kind):: radiance, radiance_overcast, radiance_ratio
real(r_kind),dimension(0:3):: wgtavg
real(r_kind),dimension(nsig,nchanl):: omix
real(r_kind),dimension(nsig,nchanl,n_aerosols_jac):: jaero
@@ -2201,6 +2206,7 @@ subroutine call_crtm(obstype,obstime,data_s,nchanl,nreal,ich, &
end if
endif
+
if (trim(obstype) /= 'modis_aod' .and. trim(obstype) /= 'viirs_aod' ) then
! Secant of satellite zenith angle
@@ -2217,6 +2223,8 @@ subroutine call_crtm(obstype,obstime,data_s,nchanl,nreal,ich, &
end do
end if
+ chan_level = zero
+
!$omp parallel do schedule(dynamic,1) private(i) &
!$omp private(total_od,k,kk,m,term,ii,cwj)
do i=1,nchanl
@@ -2228,6 +2236,17 @@ subroutine call_crtm(obstype,obstime,data_s,nchanl,nreal,ich, &
wmix(k,i)=zero
end do
+ radiance=rtsolution(i,1)%radiance
+ do k=msig, 1, -1
+ radiance_overcast = rtsolution(i,1)%upwelling_overcast_radiance(k)
+ radiance_ratio = abs(radiance_overcast/radiance)
+ if (radiance_ratio < 0.99_r_kind) then
+ chan_level(i) = atmosphere(1)%pressure(k) / r10
+ exit
+ endif
+ enddo
+
+
! Simulated brightness temperatures
tsim(i)=rtsolution(i,1)%brightness_temperature
diff --git a/src/gsi/cwhydromod.f90 b/src/gsi/cwhydromod.f90
index a27bba545f..d2bde78129 100644
--- a/src/gsi/cwhydromod.f90
+++ b/src/gsi/cwhydromod.f90
@@ -100,14 +100,23 @@ subroutine cw2hydro(sval,clouds,nclouds)
call gsi_bundlegetpointer (sval,clouds(ic),sv_rank3,istatus)
if (istatus/=0) cycle
sv_rank3=zero
- do k=1,nsig
- do j=1,lon2
- do i=1,lat2
- if (clouds(ic)=='ql') sv_rank3(i,j,k)=cwgues(i,j,k)*(one-work(i,j,k))
- if (clouds(ic)=='qi') sv_rank3(i,j,k)=cwgues(i,j,k)*work(i,j,k)
+ if (clouds(ic)=='ql') then
+ do k=1,nsig
+ do j=1,lon2
+ do i=1,lat2
+ sv_rank3(i,j,k)=cwgues(i,j,k)*(one-work(i,j,k))
+ end do
end do
end do
- end do
+ else if (clouds(ic)=='qi') then
+ do k=1,nsig
+ do j=1,lon2
+ do i=1,lat2
+ sv_rank3(i,j,k)=cwgues(i,j,k)*work(i,j,k)
+ end do
+ end do
+ end do
+ end if
end do
return
@@ -174,16 +183,25 @@ subroutine cw2hydro_tl(sval,wbundle,clouds,nclouds)
call gsi_bundlegetpointer (sval,clouds(ic),sv_rank3,istatus)
if (istatus/=0) cycle
sv_rank3=zero
- do k=1,nsig
- do j=1,lon2
- do i=1,lat2
-! if (clouds(ic)=='ql') sv_rank3(i,j,k)=cv_cw(i,j,k)*(one-work0(i,j,k))-cwgues(i,j,k)*work(i,j,k)
-! if (clouds(ic)=='qi') sv_rank3(i,j,k)=cv_cw(i,j,k)*work0(i,j,k)+cwgues(i,j,k)*work(i,j,k)
- if (clouds(ic)=='ql') sv_rank3(i,j,k)=cv_cw(i,j,k)*(one-work0(i,j,k))
- if (clouds(ic)=='qi') sv_rank3(i,j,k)=cv_cw(i,j,k)*work0(i,j,k)
+ if (clouds(ic)=='ql') then
+ do k=1,nsig
+ do j=1,lon2
+ do i=1,lat2
+! sv_rank3(i,j,k)=cv_cw(i,j,k)*(one-work0(i,j,k))-cwgues(i,j,k)*work(i,j,k)
+ sv_rank3(i,j,k)=cv_cw(i,j,k)*(one-work0(i,j,k))
+ end do
end do
end do
- end do
+ else if (clouds(ic)=='qi') then
+ do k=1,nsig
+ do j=1,lon2
+ do i=1,lat2
+! sv_rank3(i,j,k)=cv_cw(i,j,k)*work0(i,j,k)+cwgues(i,j,k)*work(i,j,k)
+ sv_rank3(i,j,k)=cv_cw(i,j,k)*work0(i,j,k)
+ end do
+ end do
+ end do
+ end if
end do
return
@@ -226,8 +244,6 @@ subroutine cw2hydro_ad(rval,wbundle,clouds,nclouds)
real(r_kind),pointer,dimension(:,:,:) :: cv_cw
! Get pointer to required control variable
-call gsi_bundlegetpointer (wbundle,'cw',cv_cw,istatus)
-cv_cw=zero
do k=1,nsig
do j=1,lon2
@@ -239,25 +255,30 @@ subroutine cw2hydro_ad(rval,wbundle,clouds,nclouds)
end do
end do
+call gsi_bundlegetpointer (wbundle,'cw',cv_cw,istatus)
do ic=1,nclouds
call gsi_bundlegetpointer (rval,clouds(ic),rv_rank3,istatus)
if (istatus/=0) cycle
- do k=1,nsig
- do j=1,lon2
- do i=1,lat2
- if (clouds(ic)=='ql') then
+ if (clouds(ic)=='ql') then
+ do k=1,nsig
+ do j=1,lon2
+ do i=1,lat2
cv_cw(i,j,k)=cv_cw(i,j,k)+rv_rank3(i,j,k)*(one-work0(i,j,k))
rv_rank3(i,j,k)=zero
- end if
-
- if (clouds(ic)=='qi') then
+ end do
+ end do
+ end do
+ else if (clouds(ic)=='qi') then
+ do k=1,nsig
+ do j=1,lon2
+ do i=1,lat2
cv_cw(i,j,k)=cv_cw(i,j,k)+rv_rank3(i,j,k)*work0(i,j,k)
rv_rank3(i,j,k)=zero
- end if
-
+ end do
end do
end do
- end do
+ end if
+
end do
return
diff --git a/src/gsi/deter_sfc_mod.f90 b/src/gsi/deter_sfc_mod.f90
index 3c88aabb2a..271e81c5d2 100644
--- a/src/gsi/deter_sfc_mod.f90
+++ b/src/gsi/deter_sfc_mod.f90
@@ -33,7 +33,7 @@ module deter_sfc_mod
use satthin, only: sno_full,isli_full,sst_full,soil_moi_full, &
soil_temp_full,soil_type_full,veg_frac_full,veg_type_full, &
fact10_full,zs_full,sfc_rough_full,zs_full_gfs
- use constants, only: zero,one,two,one_tenth,deg2rad,rad2deg
+ use constants, only: zero,one,two,one_tenth,deg2rad,rad2deg, rearth
use gridmod, only: nlat,nlon,regional,tll2xy,nlat_sfc,nlon_sfc,rlats_sfc,rlons_sfc, &
rlats,rlons,dx_gfs,txy2ll,lpl_gfs
use guess_grids, only: nfldsfc,hrdifsfc,ntguessfc
@@ -156,7 +156,7 @@ subroutine deter_sfc(alat,alon,dlat_earth,dlon_earth,obstime,isflg, &
if(iyp==nlon_sfc+1) iyp=1
! Get time interpolation factors for surface files
- if(obstime > hrdifsfc(1) .and. obstime <= hrdifsfc(nfldsfc))then
+ if(obstime > hrdifsfc(1) .and. obstime < hrdifsfc(nfldsfc))then
do j=1,nfldsfc-1
if(obstime > hrdifsfc(j) .and. obstime <= hrdifsfc(j+1))then
itsfc=j
@@ -207,7 +207,6 @@ subroutine deter_sfc(alat,alon,dlat_earth,dlon_earth,obstime,isflg, &
sfcpct(istyp10)=sfcpct(istyp10)+w10
sfcpct(istyp11)=sfcpct(istyp11)+w11
- isflg = 0
if(sfcpct(0) > 0.99_r_kind)then
isflg = 0
else if(sfcpct(1) > 0.99_r_kind)then
@@ -465,7 +464,7 @@ subroutine deter_sfc_type(dlat_earth,dlon_earth,obstime,isflg,tsavg)
if(iyp==nlon_sfc+1) iyp=1
! Get time interpolation factors for surface files
- if(obstime > hrdifsfc(1) .and. obstime <= hrdifsfc(nfldsfc))then
+ if(obstime > hrdifsfc(1) .and. obstime < hrdifsfc(nfldsfc))then
do j=1,nfldsfc-1
if(obstime > hrdifsfc(j) .and. obstime <= hrdifsfc(j+1))then
itsfc=j
@@ -517,7 +516,6 @@ subroutine deter_sfc_type(dlat_earth,dlon_earth,obstime,isflg,tsavg)
sfcpct(istyp10)=sfcpct(istyp10)+w10
sfcpct(istyp11)=sfcpct(istyp11)+w11
- isflg = 0
if(sfcpct(0) > 0.99_r_kind)then
isflg = 0
else if(sfcpct(1) > 0.99_r_kind)then
@@ -602,7 +600,7 @@ subroutine deter_sfc2(dlat_earth,dlon_earth,obstime,idomsfc,tsavg,ff10,sfcr,zz)
! Get time interpolation factors for surface files
- if(obstime > hrdifsfc(1) .and. obstime <= hrdifsfc(nfldsfc))then
+ if(obstime > hrdifsfc(1) .and. obstime < hrdifsfc(nfldsfc))then
do j=1,nfldsfc-1
if(obstime > hrdifsfc(j) .and. obstime <= hrdifsfc(j+1))then
itsfc=j
@@ -823,7 +821,7 @@ subroutine deter_sfc_fov(fov_flag,ifov,instr,ichan,sat_aziang,dlat_earth_deg,&
! Get time interpolation factors for surface files
- if(obstime > hrdifsfc(1) .and. obstime <= hrdifsfc(nfldsfc))then
+ if(obstime > hrdifsfc(1) .and. obstime < hrdifsfc(nfldsfc))then
do j=1,nfldsfc-1
if(obstime > hrdifsfc(j) .and. obstime <= hrdifsfc(j+1))then
itsfc=j
@@ -1050,21 +1048,21 @@ subroutine deter_sfc_fov(fov_flag,ifov,instr,ichan,sat_aziang,dlat_earth_deg,&
exit loop1
endif
- mid = (float(subgrid_lengths_y)-one)/two + one
- del = one/ float(subgrid_lengths_y)
+ mid = (real(subgrid_lengths_y,r_kind)-one)/two + one
+ del = one/ real(subgrid_lengths_y,r_kind)
allocate (y_off(subgrid_lengths_y))
do i= 1, subgrid_lengths_y
- y_off(i) = (float(i)-mid)*del
+ y_off(i) = (real(i,r_kind)-mid)*del
enddo
- mid = (float(subgrid_lengths_x)-one)/two + one
- del = one / float(subgrid_lengths_x)
+ mid = (real(subgrid_lengths_x,r_kind)-one)/two + one
+ del = one / real(subgrid_lengths_x,r_kind)
allocate (x_off(subgrid_lengths_x))
do i= 1, subgrid_lengths_x
- x_off(i) = (float(i)-mid)*del
+ x_off(i) = (real(i,r_kind)-mid)*del
enddo
! Determine the surface characteristics by integrating over the
@@ -1077,9 +1075,9 @@ subroutine deter_sfc_fov(fov_flag,ifov,instr,ichan,sat_aziang,dlat_earth_deg,&
do i = min_i(j), max_i(j)
call time_int_sfc(i,j,itsfc,itsfcp,dtsfc,dtsfcp,sfc_mdl)
do jjj = 1, subgrid_lengths_y
- y = float(j) + y_off(jjj)
+ y = real(j,r_kind) + y_off(jjj)
do iii = 1, subgrid_lengths_x
- x = float(i) + x_off(iii)
+ x = real(i,r_kind) + x_off(iii)
call txy2ll(x,y,lon_rad,lat_rad)
lat_mdl = lat_rad*rad2deg
lon_mdl = lon_rad*rad2deg
@@ -1109,7 +1107,7 @@ subroutine deter_sfc_fov(fov_flag,ifov,instr,ichan,sat_aziang,dlat_earth_deg,&
do i = min_i(j), max_i(j)
call reduce2full(i,j,ifull)
call time_int_sfc(ifull,j,itsfc,itsfcp,dtsfc,dtsfcp,sfc_mdl)
-!$omp parallel do schedule(dynamic,1)private(jjj,iii,lat_mdl,lon_mdl)
+!$omp parallel do schedule(dynamic,1) private(jjj,iii,lat_mdl,lon_mdl)
do jjj = 1, subgrid_lengths_y
if (y_off(jjj) >= zero) then
lat_mdl = (one-y_off(jjj))*rlats_sfc(j)+y_off(jjj)*rlats_sfc(j+1)
@@ -1122,7 +1120,7 @@ subroutine deter_sfc_fov(fov_flag,ifov,instr,ichan,sat_aziang,dlat_earth_deg,&
! ok here when calculating longitude even if the value is
! greater than 360. the ellipse code works from longitude relative
! to the center of the fov.
- lon_mdl = (float(i)+x_off(iii) - one) * dx_gfs(jj)
+ lon_mdl = (real(i,r_kind)+x_off(iii) - one) * dx_gfs(jj)
if (fov_flag=="crosstrk")then
call inside_fov_crosstrk(instr,ifov,sat_aziang, &
dlat_earth_deg,dlon_earth_deg, &
@@ -1316,7 +1314,6 @@ subroutine deter_sfc_amsre_low(dlat_earth,dlon_earth,isflg,sfcpct)
! sfcpct(3)=min(sfcpct(3),sfcpct(1))
! sfcpct(1)=max(zero,sfcpct(1)-sfcpct(3))
- isflg = 0
if(sfcpct(0) > 0.99_r_kind)then
isflg = 0
else if(sfcpct(1) > 0.99_r_kind)then
@@ -1334,7 +1331,7 @@ subroutine deter_sfc_amsre_low(dlat_earth,dlon_earth,isflg,sfcpct)
end subroutine deter_sfc_amsre_low
-subroutine deter_sfc_gmi(dlat_earth,dlon_earth,isflg,sfcpct)
+subroutine deter_sfc_gmi(dlat_earth,dlon_earth,isflg)
!$$$ subprogram documentation block
! . . . .
! subprogram: deter_sfc_gmi determine land surface type
@@ -1357,11 +1354,6 @@ subroutine deter_sfc_gmi(dlat_earth,dlon_earth,isflg,sfcpct)
! 2 sea ice
! 3 snow
! 4 mixed
-! sfcpct(0:3)- percentage of 4 surface types
-! (0) - sea percentage
-! (1) - land percentage
-! (2) - sea ice percentage
-! (3) - snow percentage
!
! attributes:
! language: f90
@@ -1373,15 +1365,11 @@ subroutine deter_sfc_gmi(dlat_earth,dlon_earth,isflg,sfcpct)
real(r_kind) ,intent(in ) :: dlat_earth,dlon_earth
integer(i_kind) ,intent( out) :: isflg
- real(r_kind),dimension(0:3),intent( out) :: sfcpct
-
- integer(i_kind) jsli,it
- integer(i_kind):: klat1,klon1,klatp1,klonp1
- real(r_kind):: dx,dy,dx1,dy1,w00,w10,w01,w11
- real(r_kind) :: dlat,dlon
+ integer(i_kind) jsli,it, i, j
+ integer(i_kind):: klat1,klon1,klatp1,klonp1, ksmall, klarge, n_grid
+ real(r_kind) :: dlat,dlon, grid_dist
+ integer(i_kind):: klatn,klonn,klatpn,klonpn
logical :: outside
- integer(i_kind):: klat2,klon2,klatp2,klonp2
-
!
! For interpolation, we usually use o points (4points for land sea decision)
! In case of lowfreq channel (Large FOV), add the check of x points(8 points)
@@ -1410,91 +1398,55 @@ subroutine deter_sfc_gmi(dlat_earth,dlon_earth,isflg,sfcpct)
end if
klon1=int(dlon); klat1=int(dlat)
- dx =dlon-klon1; dy =dlat-klat1
- dx1 =one-dx; dy1 =one-dy
- w00=dx1*dy1; w10=dx1*dy; w01=dx*dy1; w11=dx*dy
klat1=min(max(1,klat1),nlat_sfc); klon1=min(max(0,klon1),nlon_sfc)
if(klon1==0) klon1=nlon_sfc
klatp1=min(nlat_sfc,klat1+1); klonp1=klon1+1
- if(klonp1==nlon_sfc+1) klonp1=1
- klonp2 = klonp1+1
- if(klonp2==nlon_sfc+1) klonp2=1
- klon2=klon1-1
- if(klon2==0)klon2=nlon_sfc
- klat2=max(1,klat1-1)
- klatp2=min(nlat_sfc,klatp1+1)
! Set surface type flag. Begin by assuming obs over ice-free water
- sfcpct = zero
-
- jsli = isli_full(klat1 ,klon1 )
- if(sno_full(klat1 ,klon1 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- jsli = isli_full(klatp1,klon1 )
- if(sno_full(klatp1 ,klon1 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- jsli = isli_full(klat1 ,klonp1)
- if(sno_full(klat1 ,klonp1 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- jsli = isli_full(klatp1,klonp1)
- if(sno_full(klatp1 ,klonp1 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- jsli = isli_full(klatp2,klon1)
- if(sno_full(klatp2 ,klon1 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- jsli = isli_full(klatp2,klonp1)
- if(sno_full(klatp2 ,klonp1 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- jsli = isli_full(klatp1,klon2)
- if(sno_full(klatp1 ,klon2 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- jsli = isli_full(klatp1,klonp2)
- if(sno_full(klatp1 ,klonp2 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- jsli = isli_full(klat1,klon2)
- if(sno_full(klat1 ,klon2 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- jsli = isli_full(klat1,klonp2)
- if(sno_full(klat1 ,klonp2 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- jsli = isli_full(klat2,klon1)
- if(sno_full(klat2 ,klon1 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- jsli = isli_full(klat2,klonp1)
- if(sno_full(klat2 ,klonp1 ,it) > one .and. jsli == 1)jsli=3
- sfcpct(jsli)=sfcpct(jsli)+one
-
- sfcpct=sfcpct/12.0_r_kind
-
-! sfcpct(3)=min(sfcpct(3),sfcpct(1))
-! sfcpct(1)=max(zero,sfcpct(1)-sfcpct(3))
-
- isflg = 0
- if(sfcpct(0) > 0.99_r_kind)then
- isflg = 0
- else if(sfcpct(1) > 0.99_r_kind)then
- isflg = 1
- else if(sfcpct(2) > 0.99_r_kind)then
- isflg = 2
- else if(sfcpct(3) > 0.99_r_kind)then
- isflg = 3
- else
- isflg = 4
- end if
+ grid_dist=rearth * (rlats_sfc(klatp1) - rlats_sfc(klat1))
+ n_grid=int(40000 / grid_dist) + 1
+ klatn = max(klat1 - n_grid, 1)
+ klonn = klon1 - n_grid
+ if (klonn < 0) klonn = nlon_sfc - klonn
+ klatpn = min((klat1 + n_grid), nlat_sfc)
+ klonpn = klon1 + n_grid
+ if (klonpn > nlon_sfc) klonpn = klonpn - nlon_sfc
+
+ isflg=0
+ outer: do i = klatn, klatpn
+ ! assume n_grid > 2
+ if (0 < klonpn - klonn .and. klonpn - klonn < nlon_sfc / 2) then
+ do j = klonn, klonpn
+ if (isli_full(i, j) /= 0) then
+ isflg = 1
+ exit outer
+ end if
+ end do
+ else
+ if (klonpn < klonn) then
+ ksmall = klonpn
+ klarge = klonn
+ else
+ ksmall = klonn
+ klarge = klonpn
+ end if
+ do j = 1, ksmall
+ if (isli_full(i, j) /= 0) then
+ isflg = 1
+ exit outer
+ endif
+ end do
+ do j = klarge, nlon_sfc
+ if (isli_full(i, j) /= 0) then
+ isflg = 1
+ exit outer
+ end if
+ end do
+ end if
+ end do outer
return
end subroutine deter_sfc_gmi
@@ -1920,7 +1872,7 @@ subroutine calc_sfc(sfc_sum,isflg,idomsfc,sfcpct,vfr,sty,vty,sm, &
vty=zero
else
itmp=lbound(sfc_sum%count_vty)-1+maxloc(sfc_sum%count_vty)
- vty=float(itmp(1))
+ vty=real(itmp(1),r_kind)
endif
! soil type is predominate type
@@ -1929,7 +1881,7 @@ subroutine calc_sfc(sfc_sum,isflg,idomsfc,sfcpct,vfr,sty,vty,sm, &
sty=zero
else
itmp=lbound(sfc_sum%count_sty)-1+maxloc(sfc_sum%count_sty)
- sty=float(itmp(1))
+ sty=real(itmp(1),r_kind)
endif
! fields for bare (non-snow covered) land
@@ -1986,7 +1938,6 @@ subroutine calc_sfc(sfc_sum,isflg,idomsfc,sfcpct,vfr,sty,vty,sm, &
sfcr = sfc_sum%sfcr/count_tot
zz = sfc_sum%zz/count_tot
- isflg = 0
if(sfcpct(0) > 0.99_r_kind)then
isflg = 0 ! open water
else if(sfcpct(1) > 0.99_r_kind)then
diff --git a/src/gsi/ens_spread_mod.f90 b/src/gsi/ens_spread_mod.f90
index da70d31ab0..c6528f64ff 100644
--- a/src/gsi/ens_spread_mod.f90
+++ b/src/gsi/ens_spread_mod.f90
@@ -78,7 +78,7 @@ subroutine ens_spread_dualres_regional(en_bar)
call stop2(999)
endif
- sp_norm=(one/float(n_ens))
+ sp_norm=(one/real(n_ens,r_kind))
sube%values=zero
!
diff --git a/src/gsi/ensctl2model.f90 b/src/gsi/ensctl2model.f90
index 12e1fe374e..8a042a1e6a 100644
--- a/src/gsi/ensctl2model.f90
+++ b/src/gsi/ensctl2model.f90
@@ -52,7 +52,7 @@ subroutine ensctl2model(xhat,mval,eval)
type(gsi_bundle) , intent(inout) :: eval(ntlevs_ens)
! Declare local variables
-character(len=*),parameter::myname='ensctl2state'
+character(len=*),parameter::myname='ensctl2model'
character(len=max_varname_length),allocatable,dimension(:) :: clouds
integer(i_kind) :: jj,ic,id,istatus,nclouds,nn
@@ -140,7 +140,7 @@ subroutine ensctl2model(xhat,mval,eval)
eval(jj)%values=zero
! Create a temporary bundle similar to xhat, and copy contents of xhat into it
- call gsi_bundlecreate ( wbundle_c, xhat%step(1), 'ensctl2state work', istatus )
+ call gsi_bundlecreate ( wbundle_c, xhat%step(1), 'ensctl2model work', istatus )
if(istatus/=0) then
write(6,*) trim(myname), ': trouble creating work bundle'
call stop2(999)
diff --git a/src/gsi/ensctl2model_ad.f90 b/src/gsi/ensctl2model_ad.f90
index 706dafc59c..4adf4486f2 100644
--- a/src/gsi/ensctl2model_ad.f90
+++ b/src/gsi/ensctl2model_ad.f90
@@ -51,7 +51,7 @@ subroutine ensctl2model_ad(eval,mval,grad)
type(gsi_bundle) , intent(in ) :: eval(ntlevs_ens)
! Declare local variables
-character(len=*),parameter::myname='ensctl2state'
+character(len=*),parameter::myname='ensctl2model_ad'
character(len=max_varname_length),allocatable,dimension(:) :: clouds
integer(i_kind) :: ii,jj,ic,id,istatus,nclouds,nn
diff --git a/src/gsi/ensctl2state.f90 b/src/gsi/ensctl2state.f90
index 0d6d3042c5..4afc87d56e 100644
--- a/src/gsi/ensctl2state.f90
+++ b/src/gsi/ensctl2state.f90
@@ -1,4 +1,66 @@
-subroutine ensctl2state(xhat,mval,eval)
+!-------------------------------------------------------------------------
+! NOAA/NCEP, National Centers for Environmental Prediction GSI !
+!-------------------------------------------------------------------------
+!BOP
+!
+! !MODULE: ensctl2state_mod --- ensctl2state_mod variables and routines
+!
+! !INTERFACE:
+!
+module ensctl2state_mod
+
+! !USES:
+
+
+! !DESCRIPTION: module ensctl2state routines and variables
+
+
+use constants, only: zero,max_varname_length
+use kinds, only: r_kind,i_kind
+use control_vectors, only: control_vector,cvars3d,e2sset_flg
+use gsi_4dvar, only: ibin_anl
+use hybrid_ensemble_parameters, only: uv_hyb_ens,dual_res,ntlevs_ens,q_hyb_ens
+use hybrid_ensemble_isotropic, only: ensemble_forward_model,ensemble_forward_model_dual_res
+use hybrid_ensemble_isotropic, only: ensemble_forward_model_ad,ensemble_forward_model_ad_dual_res
+use balmod, only: strong_bk,strong_bk_ad
+use gsi_bundlemod, only: gsi_bundlecreate
+use gsi_bundlemod, only: gsi_bundle
+use gsi_bundlemod, only: gsi_bundlegetpointer
+use gsi_bundlemod, only: gsi_bundlegetvar
+use gsi_bundlemod, only: gsi_bundleputvar
+use gsi_bundlemod, only: gsi_bundledestroy
+use gsi_bundlemod, only: self_add
+use gsi_bundlemod, only: assignment(=)
+use mpeu_util, only: getindex
+use gsi_metguess_mod, only: gsi_metguess_get
+use mod_strong, only: tlnmc_option
+use cwhydromod, only: cw2hydro_tl,cw2hydro_ad
+use cwhydromod, only: cw2hydro_tl_hwrf,cw2hydro_ad_hwrf
+use timermod, only: timer_ini,timer_fnl
+use gridmod, only: nems_nmmb_regional
+
+implicit none
+
+private
+public :: ensctl2state,ensctl2state_ad
+
+logical :: ls_u,ls_v,ls_prse,ls_q,ls_tsen,ls_ql,ls_qi
+logical :: ls_qr,ls_qs,ls_qg,ls_qh
+logical :: ls_w,ls_dw
+
+logical :: lc_sf,lc_vp,lc_ps,lc_t,lc_rh,lc_cw
+logical :: lc_w,lc_dw
+
+logical :: do_getuv,do_tv_to_tsen,do_normal_rh_to_q,do_getprs,lstrong_bk_vars
+logical :: do_q_copy
+logical :: do_cw_to_hydro
+logical :: do_cw_to_hydro_hwrf
+
+integer(i_kind) :: nclouds,idozone,istatus
+
+
+contains
+ subroutine ensctl2state(xhat,mval,eval)
!$$$ subprogram documentation block
! . . . .
! subprogram: ensctl2state
@@ -25,28 +87,6 @@ subroutine ensctl2state(xhat,mval,eval)
!
!$$$ end documentation block
-use constants, only: zero,max_varname_length
-use kinds, only: r_kind,i_kind
-use control_vectors, only: control_vector,cvars3d
-use gsi_4dvar, only: ibin_anl
-use hybrid_ensemble_parameters, only: uv_hyb_ens,dual_res,ntlevs_ens,q_hyb_ens
-use hybrid_ensemble_isotropic, only: ensemble_forward_model,ensemble_forward_model_dual_res
-use balmod, only: strong_bk
-use gsi_bundlemod, only: gsi_bundlecreate
-use gsi_bundlemod, only: gsi_bundle
-use gsi_bundlemod, only: gsi_bundlegetpointer
-use gsi_bundlemod, only: gsi_bundlegetvar
-use gsi_bundlemod, only: gsi_bundleputvar
-use gsi_bundlemod, only: gsi_bundledestroy
-use gsi_bundlemod, only: self_add
-use gsi_bundlemod, only: assignment(=)
-use mpeu_util, only: getindex
-use gsi_metguess_mod, only: gsi_metguess_get
-use mod_strong, only: tlnmc_option
-use cwhydromod, only: cw2hydro_tl
-use cwhydromod, only: cw2hydro_tl_hwrf
-use timermod, only: timer_ini,timer_fnl
-use gridmod, only: nems_nmmb_regional
implicit none
! Declare passed variables
@@ -57,28 +97,14 @@ subroutine ensctl2state(xhat,mval,eval)
! Declare local variables
character(len=*),parameter::myname='ensctl2state'
character(len=max_varname_length),allocatable,dimension(:) :: clouds
-integer(i_kind) :: jj,ic,id,istatus,nclouds
+integer(i_kind) :: jj,ic,id
+logical :: do_tlnmc
-integer(i_kind), parameter :: ncvars = 8
-integer(i_kind) :: icps(ncvars)
type(gsi_bundle):: wbundle_c ! work bundle
-character(len=3), parameter :: mycvars(ncvars) = (/ & ! vars from CV needed here
- 'sf ', 'vp ', 'ps ', 't ', &
- 'q ', 'cw ', 'w ', 'dw '/)
-logical :: lc_sf,lc_vp,lc_ps,lc_t,lc_rh,lc_cw
-logical :: lc_w,lc_dw
real(r_kind),pointer,dimension(:,:,:) :: cv_sf=>NULL()
real(r_kind),pointer,dimension(:,:,:) :: cv_vp=>NULL()
real(r_kind),pointer,dimension(:,:,:) :: cv_rh=>NULL()
! Declare required local state variables
-integer(i_kind), parameter :: nsvars = 13
-integer(i_kind) :: isps(nsvars)
-character(len=4), parameter :: mysvars(nsvars) = (/ & ! vars from ST needed here
- 'u ', 'v ', 'prse', 'q ', 'tsen', 'ql ','qi ', &
- 'qr ', 'qs ', 'qg ', 'qh ', 'w ', 'dw ' /)
-logical :: ls_u,ls_v,ls_prse,ls_q,ls_tsen,ls_ql,ls_qi
-logical :: ls_qr,ls_qs,ls_qg,ls_qh
-logical :: ls_w,ls_dw
real(r_kind),pointer,dimension(:,:) :: sv_ps=>NULL()
real(r_kind),pointer,dimension(:,:) :: sv_sst=>NULL()
real(r_kind),pointer,dimension(:,:,:) :: sv_u=>NULL()
@@ -92,50 +118,20 @@ subroutine ensctl2state(xhat,mval,eval)
real(r_kind),pointer,dimension(:,:,:) :: sv_w=>NULL()
real(r_kind),pointer,dimension(:,:,:) :: sv_dw=>NULL()
-logical :: do_getprs_tl,do_normal_rh_to_q,do_tv_to_tsen,do_getuv,lstrong_bk_vars
-logical :: do_tlnmc,do_q_copy
-logical :: do_cw_to_hydro
-logical :: do_cw_to_hydro_hwrf
-
! ****************************************************************************
! Initialize timer
! call timer_ini(trim(myname))
+if(e2sset_flg)call ensctl2state_set(xhat,eval)
+
! Inquire about cloud-vars
-call gsi_metguess_get('clouds::3d',nclouds,istatus)
if (nclouds>0) then
allocate(clouds(nclouds))
call gsi_metguess_get('clouds::3d',clouds,istatus)
endif
-! Since each internal vector of xhat has the same structure, pointers are
-! the same independent of the subwindow jj
-call gsi_bundlegetpointer (xhat%step(1),mycvars,icps,istatus)
-lc_sf =icps(1)>0; lc_vp =icps(2)>0; lc_ps =icps(3)>0
-lc_t =icps(4)>0; lc_rh =icps(5)>0; lc_cw =icps(6)>0
-lc_w =icps(7)>0; lc_dw =icps(8)>0
-
-! Since each internal vector of xhat has the same structure, pointers are
-! the same independent of the subwindow jj
-call gsi_bundlegetpointer (eval(1),mysvars,isps,istatus)
-ls_u =isps(1)>0; ls_v =isps(2)>0; ls_prse=isps(3)>0
-ls_q =isps(4)>0; ls_tsen=isps(5)>0; ls_ql =isps(6)>0; ls_qi =isps(7)>0
-ls_qr =isps(8)>0; ls_qs =isps(9)>0
-ls_qg =isps(10)>0; ls_qh =isps(11)>0
-ls_w =isps(12)>0; ls_dw =isps(13)>0
-! Define what to do depending on what's in CV and SV
-lstrong_bk_vars =lc_ps.and.lc_sf.and.lc_vp.and.lc_t
-do_getprs_tl =lc_ps.and.lc_t .and.ls_prse
-do_normal_rh_to_q=(.not.q_hyb_ens).and.&
- lc_rh.and.lc_t .and.ls_prse.and.ls_q
-do_q_copy=.false.
-if(.not. do_normal_rh_to_q) then
- do_q_copy = lc_rh.and.lc_t .and.ls_prse.and.ls_q.and.q_hyb_ens
-end if
-do_tv_to_tsen =lc_t .and.ls_q .and.ls_tsen
-do_getuv =lc_sf.and.lc_vp.and.ls_u.and.ls_v
! Create a temporary bundle similar to xhat, and copy contents of xhat into it
call gsi_bundlecreate ( wbundle_c, xhat%step(1), 'ensctl2state work', istatus )
if(istatus/=0) then
@@ -143,10 +139,6 @@ subroutine ensctl2state(xhat,mval,eval)
call stop2(999)
endif
-do_cw_to_hydro = .false.
-do_cw_to_hydro = lc_cw .and. ls_ql .and. ls_qi
-do_cw_to_hydro_hwrf = .false.
-do_cw_to_hydro_hwrf = lc_cw.and.ls_ql.and.ls_qi.and.ls_qr.and.ls_qs.and.ls_qg.and.ls_qh
! Initialize ensemble contribution to zero
!$omp parallel do schedule(dynamic,1) private(jj)
@@ -205,7 +197,7 @@ subroutine ensctl2state(xhat,mval,eval)
if(do_q_copy) then
call gsi_bundlegetvar ( wbundle_c, 'q', sv_q, istatus )
else
- if(do_getprs_tl) call getprs_tl(sv_ps,sv_tv,sv_prse)
+ if(do_getprs) call getprs_tl(sv_ps,sv_tv,sv_prse)
! Convert RH to Q
if(do_normal_rh_to_q) then
@@ -239,24 +231,23 @@ subroutine ensctl2state(xhat,mval,eval)
!$omp section
-! Get pointers to required state variables
- call gsi_bundlegetpointer (eval(jj),'oz' ,sv_oz , istatus)
+! Get pointers to required state variables and copy
call gsi_bundlegetpointer (eval(jj),'sst' ,sv_sst, istatus)
- if(ls_w)then
+ call gsi_bundlegetvar ( wbundle_c, 'sst', sv_sst, istatus )
+ if(ls_w .and. lc_w)then
call gsi_bundlegetpointer (eval(jj),'w' ,sv_w, istatus)
- if(ls_dw.and.nems_nmmb_regional)then
+ call gsi_bundlegetvar ( wbundle_c, 'w' , sv_w, istatus )
+ if(ls_dw .and. lc_dw)then
call gsi_bundlegetpointer (eval(jj),'dw' ,sv_dw, istatus)
+ call gsi_bundlegetvar ( wbundle_c, 'dw' , sv_dw, istatus )
end if
end if
-! Copy variables
- call gsi_bundlegetvar ( wbundle_c, 'oz' , sv_oz, istatus )
- call gsi_bundlegetvar ( wbundle_c, 'sst', sv_sst, istatus )
- if(lc_w)then
- call gsi_bundlegetvar ( wbundle_c, 'w' , sv_w, istatus )
- if(lc_dw.and.nems_nmmb_regional)then
- call gsi_bundlegetvar ( wbundle_c, 'dw' , sv_dw, istatus )
- end if
- end if
+
+! Get the ozone vector if it is defined
+ if(idozone > 0) then
+ call gsi_bundlegetpointer (eval(jj),'oz' ,sv_oz , istatus)
+ call gsi_bundlegetvar ( wbundle_c, 'oz' , sv_oz, istatus )
+ endif
!$omp end parallel sections
@@ -270,7 +261,7 @@ subroutine ensctl2state(xhat,mval,eval)
! Need to update 3d pressure and sensible temperature again for consistency
! Get 3d pressure
- if(do_getprs_tl) call getprs_tl(sv_ps,sv_tv,sv_prse)
+ if(do_getprs) call getprs_tl(sv_ps,sv_tv,sv_prse)
end if
@@ -292,3 +283,287 @@ subroutine ensctl2state(xhat,mval,eval)
return
end subroutine ensctl2state
+
+subroutine ensctl2state_set(xhat,eval)
+! . . . .
+! subprogram: ensctl2state_set
+! prgmmr: derber
+!
+! abstract: Sets flags for ensctl2state and ensctl2state_ad
+!
+! program history log:
+! 2022-08-30 derber - initial code from control2state
+
+! input argument list:
+! xhat - Control variable
+! sval - State variable
+!
+!$$$ end documentation block
+
+implicit none
+
+type(control_vector), intent(in) :: xhat
+type(gsi_bundle) , intent(in) :: eval(ntlevs_ens)
+
+integer(i_kind), parameter :: nsvars = 13
+integer(i_kind) :: isps(nsvars)
+character(len=4), parameter :: mysvars(nsvars) = (/ & ! vars from ST needed here
+ 'u ', 'v ', 'prse', 'q ', 'tsen', 'ql ','qi ', &
+ 'qr ', 'qs ', 'qg ', 'qh ', 'w ', 'dw ' /)
+integer(i_kind), parameter :: ncvars = 8
+integer(i_kind) :: icps(ncvars)
+character(len=3), parameter :: mycvars(ncvars) = (/ & ! vars from CV needed here
+ 'sf ', 'vp ', 'ps ', 't ', &
+ 'q ', 'cw ', 'w ', 'dw '/)
+! Inquire about cloud-vars
+call gsi_metguess_get('clouds::3d',nclouds,istatus)
+
+! Since each internal vector of xhat has the same structure, pointers are
+! the same independent of the subwindow jj
+call gsi_bundlegetpointer (xhat%step(1),mycvars,icps,istatus)
+lc_sf =icps(1)>0; lc_vp =icps(2)>0; lc_ps =icps(3)>0
+lc_t =icps(4)>0; lc_rh =icps(5)>0; lc_cw =icps(6)>0
+lc_w =icps(7)>0; lc_dw =icps(8)>0
+
+! Since each internal vector of xhat has the same structure, pointers are
+! the same independent of the subwindow jj
+call gsi_bundlegetpointer (eval(1),mysvars,isps,istatus)
+ls_u =isps(1)>0; ls_v =isps(2)>0; ls_prse=isps(3)>0
+ls_q =isps(4)>0; ls_tsen=isps(5)>0; ls_ql =isps(6)>0; ls_qi =isps(7)>0
+ls_qr =isps(8)>0; ls_qs =isps(9)>0
+ls_qg =isps(10)>0; ls_qh =isps(11)>0
+ls_w =isps(12)>0; ls_dw =isps(13)>0.and.nems_nmmb_regional
+
+! Define what to do depending on what's in CV and SV
+lstrong_bk_vars =lc_ps.and.lc_sf.and.lc_vp.and.lc_t
+do_getprs =lc_ps.and.lc_t .and.ls_prse
+do_normal_rh_to_q=(.not.q_hyb_ens).and.&
+ lc_rh.and.lc_t .and.ls_prse.and.ls_q
+if(.not. do_normal_rh_to_q) then
+ do_q_copy = lc_rh.and.lc_t .and.ls_prse.and.ls_q.and.q_hyb_ens
+else
+ do_q_copy=.false.
+end if
+do_tv_to_tsen =lc_t .and.ls_q .and.ls_tsen
+do_getuv =lc_sf.and.lc_vp.and.ls_u.and.ls_v
+
+do_cw_to_hydro = lc_cw .and. ls_ql .and. ls_qi
+do_cw_to_hydro_hwrf = lc_cw.and.ls_ql.and.ls_qi.and.ls_qr.and.ls_qs.and.ls_qg.and.ls_qh
+
+
+idozone=getindex(cvars3d,"oz")
+
+e2sset_flg=.false. ! set to true in setup. set to false after first (only) call to ensctl2state_set
+
+
+return
+end subroutine ensctl2state_set
+subroutine ensctl2state_ad(eval,mval,grad)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: ensctl2state_ad
+! prgmmr: kleist
+!
+! abstract: Contribution from state space to ensemble control vector
+!
+! program history log:
+! 2011-11-17 kleist - initial code
+! 2013-10-28 todling - rename p3d to prse
+! 2013-11-22 kleist - add option for q perturbations
+! 2014-12-03 derber - introduce parallel regions for optimization
+! 2017-05-12 Y. Wang and X. Wang - add w as state variable for rw DA, POC: xuguang.wang@ou.edu
+! 2019-07-11 Todling - there should be no need to check on the existence of w and dw
+!
+! input argument list:
+! eval - Ensemble state variable variable
+! grad - Control variable
+!
+! output argument list:
+! grad - Control variable
+!
+!$$$ end documentation block
+
+implicit none
+
+! Declare passed variables
+type(control_vector), intent(inout) :: grad
+type(gsi_bundle) , intent(inout) :: mval
+type(gsi_bundle) , intent(in ) :: eval(ntlevs_ens)
+
+! Declare local variables
+character(len=*),parameter::myname='ensctl2state_ad'
+integer(i_kind) :: jj,ic,id
+logical :: do_tlnmc
+
+character(len=max_varname_length),allocatable,dimension(:) :: clouds
+type(gsi_bundle):: wbundle_c ! work bundle
+real(r_kind),pointer,dimension(:,:,:) :: cv_sf=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: cv_vp=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: cv_rh=>NULL()
+! Declare required local state variables
+real(r_kind),pointer,dimension(:,:) :: rv_ps=>NULL()
+real(r_kind),pointer,dimension(:,:) :: rv_sst=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_u=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_v=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_prse=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_q=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_tsen=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_tv=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_oz=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_rank3=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_w=>NULL()
+real(r_kind),pointer,dimension(:,:,:) :: rv_dw=>NULL()
+
+!****************************************************************************
+
+! Initialize timer
+!call timer_ini(trim(myname))
+
+! Inquire about chemistry
+if(e2sset_flg)call ensctl2state_set(grad,eval)
+if (nclouds>0) then
+ allocate(clouds(nclouds))
+ call gsi_metguess_get('clouds::3d',clouds,istatus)
+endif
+
+! Initialize
+mval%values=zero
+! Create a temporary bundle similar to grad, and copy contents of grad into it
+call gsi_bundlecreate ( wbundle_c, grad%step(1), 'ensctl2state_ad work', istatus )
+if(istatus/=0) then
+ write(6,*) trim(myname), ': trouble creating work bundle'
+ call stop2(999)
+endif
+
+do jj=1,ntlevs_ens
+
+! If calling TLNMC, already have u,v (so set last argument to true)
+ do_tlnmc = lstrong_bk_vars .and. ( (tlnmc_option==3) .or. &
+ (jj==ibin_anl .and. tlnmc_option==2))
+
+ wbundle_c%values=zero
+
+! Get sv pointers here
+! Get pointers to required state variables
+ call gsi_bundlegetpointer (eval(jj),'u' ,rv_u, istatus)
+ call gsi_bundlegetpointer (eval(jj),'v' ,rv_v, istatus)
+ call gsi_bundlegetpointer (eval(jj),'ps' ,rv_ps, istatus)
+ call gsi_bundlegetpointer (eval(jj),'prse',rv_prse,istatus)
+ call gsi_bundlegetpointer (eval(jj),'tv' ,rv_tv, istatus)
+ call gsi_bundlegetpointer (eval(jj),'tsen',rv_tsen,istatus)
+ call gsi_bundlegetpointer (eval(jj),'q' ,rv_q , istatus)
+ call gsi_bundlegetpointer (wbundle_c,'q' ,cv_rh ,istatus)
+
+! Adjoint of consistency for sensible temperature, calculate sensible temperature
+ if(do_tv_to_tsen) call tv_to_tsen_ad(rv_tv,rv_q,rv_tsen)
+
+ if(do_tlnmc) then
+
+ ! Adjoint to convert ps to 3-d pressure
+ if(do_getprs) call getprs_ad(rv_ps,rv_tv,rv_prse)
+ rv_prse=zero
+
+ ! Adjoint of strong_bk
+ call strong_bk_ad(rv_u,rv_v,rv_ps,rv_tv,.true.)
+
+ end if
+
+ call self_add(mval,eval(jj))
+
+!$omp parallel sections private(ic,id,istatus)
+
+!$omp section
+
+! Convert RHS calculations for u,v to st/vp
+ if (do_getuv) then
+ if(uv_hyb_ens) then
+ call gsi_bundleputvar ( wbundle_c, 'sf', rv_u, istatus )
+ call gsi_bundleputvar ( wbundle_c, 'vp', rv_v, istatus )
+ else
+ call gsi_bundlegetpointer (wbundle_c,'sf' ,cv_sf ,istatus)
+ call gsi_bundlegetpointer (wbundle_c,'vp' ,cv_vp ,istatus)
+ call getuv(rv_u,rv_v,cv_sf,cv_vp,1)
+ end if
+ end if
+
+!$omp section
+
+ call gsi_bundlegetpointer (eval(jj),'sst' ,rv_sst, istatus)
+ call gsi_bundleputvar ( wbundle_c, 'sst', rv_sst, istatus )
+ if(lc_w .and. ls_w)then
+ call gsi_bundlegetpointer (eval(jj),'w' ,rv_w, istatus)
+ call gsi_bundleputvar ( wbundle_c, 'w', rv_w, istatus )
+ if(ls_dw .and. lc_dw)then
+ call gsi_bundlegetpointer (eval(jj),'dw' ,rv_dw, istatus)
+ call gsi_bundleputvar ( wbundle_c, 'dw', rv_dw, istatus )
+ end if
+ end if
+
+! Get the ozone vector if it is defined
+ if(idozone > 0) then
+ call gsi_bundlegetpointer (eval(jj),'oz' ,rv_oz , istatus)
+ call gsi_bundleputvar ( wbundle_c, 'oz', rv_oz, istatus )
+ endif
+
+!$omp section
+
+ if (do_cw_to_hydro .and. .not.do_cw_to_hydro_hwrf) then
+! Case when cloud-vars do not map one-to-one
+! e.g. cw-to-ql&qi
+ call cw2hydro_ad(eval(jj),wbundle_c,clouds,nclouds)
+ elseif (do_cw_to_hydro_hwrf) then
+!! Case when cloud-vars do not map one-to-one
+!! e.g. cw-to-ql&qi&qr&qs&qg&qh
+ call cw2hydro_ad_hwrf(eval(jj),wbundle_c,rv_tsen)
+ else
+! Since cloud-vars map one-to-one, take care of them together
+ do ic=1,nclouds
+ id=getindex(cvars3d,clouds(ic))
+ if (id>0) then
+ call gsi_bundlegetpointer (eval(jj),clouds(ic),rv_rank3,istatus)
+ call gsi_bundleputvar (wbundle_c, clouds(ic),rv_rank3,istatus)
+ endif
+ enddo
+ endif
+
+! Calculate sensible temperature
+ if(do_q_copy) then
+ call gsi_bundleputvar (wbundle_c, 'q', rv_q, istatus )
+ else
+
+! Adjoint of convert input normalized RH to q to add contribution of moisture
+! to t, p , and normalized rh
+ if(do_normal_rh_to_q) call normal_rh_to_q_ad(cv_rh,rv_tv,rv_prse,rv_q)
+
+! Adjoint to convert ps to 3-d pressure
+ if(do_getprs) call getprs_ad(rv_ps,rv_tv,rv_prse)
+ end if
+
+! Adjoint of control to initial state
+ call gsi_bundleputvar ( wbundle_c, 't' , rv_tv, istatus )
+ call gsi_bundleputvar ( wbundle_c, 'ps', rv_ps, istatus )
+! call gsi_bundleputvar ( wbundle_c, 'q' , zero, istatus ) !mjk
+!$omp end parallel sections
+
+ if(dual_res) then
+ call ensemble_forward_model_ad_dual_res(wbundle_c,grad%aens(1,:,:),jj)
+ else
+ call ensemble_forward_model_ad(wbundle_c,grad%aens(1,:,:),jj)
+ end if
+
+end do
+
+call gsi_bundledestroy(wbundle_c,istatus)
+if (istatus/=0) then
+ write(6,*) trim(myname),': trouble destroying work bundle'
+ call stop2(999)
+endif
+
+if (nclouds>0) deallocate(clouds)
+
+! Finalize timer
+!call timer_fnl(trim(myname))
+
+return
+end subroutine ensctl2state_ad
+end module ensctl2state_mod
diff --git a/src/gsi/ensctl2state_ad.f90 b/src/gsi/ensctl2state_ad.f90
deleted file mode 100644
index 4c038c8c6e..0000000000
--- a/src/gsi/ensctl2state_ad.f90
+++ /dev/null
@@ -1,282 +0,0 @@
-subroutine ensctl2state_ad(eval,mval,grad)
-!$$$ subprogram documentation block
-! . . . .
-! subprogram: ensctl2state_ad
-! prgmmr: kleist
-!
-! abstract: Contribution from state space to ensemble control vector
-!
-! program history log:
-! 2011-11-17 kleist - initial code
-! 2013-10-28 todling - rename p3d to prse
-! 2013-11-22 kleist - add option for q perturbations
-! 2014-12-03 derber - introduce parallel regions for optimization
-! 2017-05-12 Y. Wang and X. Wang - add w as state variable for rw DA, POC: xuguang.wang@ou.edu
-! 2019-07-11 Todling - there should be no need to check on the existence of w and dw
-!
-! input argument list:
-! eval - Ensemble state variable variable
-! grad - Control variable
-!
-! output argument list:
-! grad - Control variable
-!
-!$$$ end documentation block
-
-use kinds, only: r_kind,i_kind
-use control_vectors, only: control_vector,cvars3d
-use gsi_4dvar, only: ibin_anl
-use hybrid_ensemble_parameters, only: uv_hyb_ens,dual_res,ntlevs_ens,q_hyb_ens
-use hybrid_ensemble_isotropic, only: ensemble_forward_model_ad
-use hybrid_ensemble_isotropic, only: ensemble_forward_model_ad_dual_res
-use balmod, only: strong_bk_ad
-use gsi_bundlemod, only: gsi_bundlecreate
-use gsi_bundlemod, only: gsi_bundle
-use gsi_bundlemod, only: gsi_bundlegetpointer
-use gsi_bundlemod, only: gsi_bundlegetvar
-use gsi_bundlemod, only: gsi_bundleputvar
-use gsi_bundlemod, only: gsi_bundledestroy
-use gsi_bundlemod, only: assignment(=)
-use gsi_bundlemod, only : self_add
-use constants, only: zero,max_varname_length
-use mpeu_util, only: getindex
-use gsi_metguess_mod, only: gsi_metguess_get
-use mod_strong, only: tlnmc_option
-use cwhydromod, only: cw2hydro_ad
-use cwhydromod, only: cw2hydro_ad_hwrf
-use timermod, only: timer_ini,timer_fnl
-use gridmod, only: nems_nmmb_regional
-implicit none
-
-! Declare passed variables
-type(control_vector), intent(inout) :: grad
-type(gsi_bundle) , intent(inout) :: mval
-type(gsi_bundle) , intent(in ) :: eval(ntlevs_ens)
-
-! Declare local variables
-character(len=*),parameter::myname='ensctl2state_ad'
-character(len=max_varname_length),allocatable,dimension(:) :: clouds
-integer(i_kind) :: jj,ic,id,istatus,nclouds
-
-integer(i_kind), parameter :: ncvars = 8
-integer(i_kind) :: icps(ncvars)
-type(gsi_bundle):: wbundle_c ! work bundle
-character(len=3), parameter :: mycvars(ncvars) = (/ & ! vars from CV needed here
- 'sf ', 'vp ', 'ps ', 't ', &
- 'q ', 'cw ', 'w ', 'dw '/)
-logical :: lc_sf,lc_vp,lc_ps,lc_t,lc_rh,lc_cw
-logical :: lc_w,lc_dw
-real(r_kind),pointer,dimension(:,:,:) :: cv_sf=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: cv_vp=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: cv_rh=>NULL()
-! Declare required local state variables
-integer(i_kind), parameter :: nsvars = 13
-integer(i_kind) :: isps(nsvars)
-character(len=4), parameter :: mysvars(nsvars) = (/ & ! vars from ST needed here
- 'u ', 'v ', 'prse', 'q ', 'tsen','ql ','qi ', &
- 'qr ', 'qs ', 'qg ', 'qh ', 'w ','dw ' /)
-logical :: ls_u,ls_v,ls_prse,ls_q,ls_tsen,ls_ql,ls_qi
-logical :: ls_qr,ls_qs,ls_qg,ls_qh
-logical :: ls_w,ls_dw
-real(r_kind),pointer,dimension(:,:) :: rv_ps=>NULL()
-real(r_kind),pointer,dimension(:,:) :: rv_sst=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_u=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_v=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_prse=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_q=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_tsen=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_tv=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_oz=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_rank3=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_w=>NULL()
-real(r_kind),pointer,dimension(:,:,:) :: rv_dw=>NULL()
-
-logical :: do_getuv,do_tv_to_tsen_ad,do_normal_rh_to_q_ad,do_getprs_ad,lstrong_bk_vars
-logical :: do_tlnmc,do_q_copy
-logical :: do_cw_to_hydro_ad
-logical :: do_cw_to_hydro_ad_hwrf
-logical :: wdw_exist
-
-!****************************************************************************
-
-! Initialize timer
-!call timer_ini(trim(myname))
-
-! Inquire about chemistry
-call gsi_metguess_get('clouds::3d',nclouds,istatus)
-if (nclouds>0) then
- allocate(clouds(nclouds))
- call gsi_metguess_get('clouds::3d',clouds,istatus)
-endif
-
-! Since each internal vector of grad has the same structure, pointers are
-! the same independent of the subwindow jj
-call gsi_bundlegetpointer (grad%step(1),mycvars,icps,istatus)
-lc_sf =icps(1)>0; lc_vp =icps(2)>0; lc_ps =icps(3)>0
-lc_t =icps(4)>0; lc_rh =icps(5)>0; lc_cw =icps(6)>0
-lc_w =icps(7)>0; lc_dw =icps(8)>0
-
-! Since each internal vector of grad has the same structure, pointers are
-! the same independent of the subwindow jj
-call gsi_bundlegetpointer (eval(1),mysvars,isps,istatus)
-ls_u =isps(1)>0; ls_v =isps(2)>0; ls_prse=isps(3)>0
-ls_q =isps(4)>0; ls_tsen=isps(5)>0; ls_ql =isps(6)>0; ls_qi =isps(7)>0
-ls_qr =isps(8)>0; ls_qs =isps(9)>0
-ls_qg =isps(10)>0; ls_qh =isps(11)>0
-ls_w =isps(12)>0; ls_dw =isps(13)>0
-
-! Define what to do depending on what's in CV and SV
-lstrong_bk_vars =lc_sf.and.lc_vp.and.lc_ps .and.lc_t
-do_getuv =lc_sf.and.lc_vp.and.ls_u .and.ls_v
-do_tv_to_tsen_ad =lc_t .and.ls_q .and.ls_tsen
-do_normal_rh_to_q_ad=(.not.q_hyb_ens).and.&
- lc_t .and.lc_rh.and.ls_prse.and.ls_q
-do_q_copy=.false.
-if(.not. do_normal_rh_to_q_ad) then
- do_q_copy = lc_rh.and.lc_t .and.ls_prse.and.ls_q.and.q_hyb_ens
-end if
-do_getprs_ad =lc_t .and.lc_ps.and.ls_prse
-
-do_cw_to_hydro_ad=.false.
-do_cw_to_hydro_ad=lc_cw.and.ls_ql.and.ls_qi
-do_cw_to_hydro_ad_hwrf=.false.
-do_cw_to_hydro_ad_hwrf=lc_cw.and.ls_ql.and.ls_qi.and.ls_qr.and.ls_qs.and.ls_qg.and.ls_qh
-
-wdw_exist = lc_w.and.lc_dw.and.ls_w.and.ls_dw
-
-! Initialize
-mval%values=zero
-! Create a temporary bundle similar to grad, and copy contents of grad into it
-call gsi_bundlecreate ( wbundle_c, grad%step(1), 'ensctl2state_ad work', istatus )
-if(istatus/=0) then
- write(6,*) trim(myname), ': trouble creating work bundle'
- call stop2(999)
-endif
-
-do jj=1,ntlevs_ens
-
-! If calling TLNMC, already have u,v (so set last argument to true)
- do_tlnmc = lstrong_bk_vars .and. ( (tlnmc_option==3) .or. &
- (jj==ibin_anl .and. tlnmc_option==2))
-
- wbundle_c%values=zero
-
-! Get sv pointers here
-! Get pointers to required state variables
- call gsi_bundlegetpointer (eval(jj),'u' ,rv_u, istatus)
- call gsi_bundlegetpointer (eval(jj),'v' ,rv_v, istatus)
- call gsi_bundlegetpointer (eval(jj),'ps' ,rv_ps, istatus)
- call gsi_bundlegetpointer (eval(jj),'prse',rv_prse,istatus)
- call gsi_bundlegetpointer (eval(jj),'tv' ,rv_tv, istatus)
- call gsi_bundlegetpointer (eval(jj),'tsen',rv_tsen,istatus)
- call gsi_bundlegetpointer (eval(jj),'q' ,rv_q , istatus)
- call gsi_bundlegetpointer (wbundle_c,'q' ,cv_rh ,istatus)
-
-! Adjoint of consistency for sensible temperature, calculate sensible temperature
- if(do_tv_to_tsen_ad) call tv_to_tsen_ad(rv_tv,rv_q,rv_tsen)
-
- if(do_tlnmc) then
-
- ! Adjoint to convert ps to 3-d pressure
- if(do_getprs_ad) call getprs_ad(rv_ps,rv_tv,rv_prse)
- rv_prse=zero
-
- ! Adjoint of strong_bk
- call strong_bk_ad(rv_u,rv_v,rv_ps,rv_tv,.true.)
-
- end if
-
- call self_add(mval,eval(jj))
-
-!$omp parallel sections private(ic,id,istatus)
-
-!$omp section
-
-! Convert RHS calculations for u,v to st/vp
- if (do_getuv) then
- if(uv_hyb_ens) then
- call gsi_bundleputvar ( wbundle_c, 'sf', rv_u, istatus )
- call gsi_bundleputvar ( wbundle_c, 'vp', rv_v, istatus )
- else
- call gsi_bundlegetpointer (wbundle_c,'sf' ,cv_sf ,istatus)
- call gsi_bundlegetpointer (wbundle_c,'vp' ,cv_vp ,istatus)
- call getuv(rv_u,rv_v,cv_sf,cv_vp,1)
- end if
- end if
-
-!$omp section
-
- call gsi_bundlegetpointer (eval(jj),'oz' ,rv_oz , istatus)
- call gsi_bundlegetpointer (eval(jj),'sst' ,rv_sst, istatus)
- call gsi_bundleputvar ( wbundle_c, 'oz', rv_oz, istatus )
- call gsi_bundleputvar ( wbundle_c, 'sst', rv_sst, istatus )
- if(wdw_exist)then
- call gsi_bundlegetpointer (eval(jj),'w' ,rv_w, istatus)
- call gsi_bundleputvar ( wbundle_c, 'w', rv_w, istatus )
- if(nems_nmmb_regional)then
- call gsi_bundlegetpointer (eval(jj),'dw' ,rv_dw, istatus)
- call gsi_bundleputvar ( wbundle_c, 'dw', rv_dw, istatus )
- end if
- end if
-
-!$omp section
-
- if (do_cw_to_hydro_ad .and. .not.do_cw_to_hydro_ad_hwrf) then
-! Case when cloud-vars do not map one-to-one
-! e.g. cw-to-ql&qi
- call cw2hydro_ad(eval(jj),wbundle_c,clouds,nclouds)
- elseif (do_cw_to_hydro_ad_hwrf) then
-!! Case when cloud-vars do not map one-to-one
-!! e.g. cw-to-ql&qi&qr&qs&qg&qh
- call cw2hydro_ad_hwrf(eval(jj),wbundle_c,rv_tsen)
- else
-! Since cloud-vars map one-to-one, take care of them together
- do ic=1,nclouds
- id=getindex(cvars3d,clouds(ic))
- if (id>0) then
- call gsi_bundlegetpointer (eval(jj),clouds(ic),rv_rank3,istatus)
- call gsi_bundleputvar (wbundle_c, clouds(ic),rv_rank3,istatus)
- endif
- enddo
- endif
-
-! Calculate sensible temperature
- if(do_q_copy) then
- call gsi_bundleputvar (wbundle_c, 'q', rv_q, istatus )
- else
-
-! Adjoint of convert input normalized RH to q to add contribution of moisture
-! to t, p , and normalized rh
- if(do_normal_rh_to_q_ad) call normal_rh_to_q_ad(cv_rh,rv_tv,rv_prse,rv_q)
-
-! Adjoint to convert ps to 3-d pressure
- if(do_getprs_ad) call getprs_ad(rv_ps,rv_tv,rv_prse)
- end if
-
-! Adjoint of control to initial state
- call gsi_bundleputvar ( wbundle_c, 't' , rv_tv, istatus )
- call gsi_bundleputvar ( wbundle_c, 'ps', rv_ps, istatus )
-! call gsi_bundleputvar ( wbundle_c, 'q' , zero, istatus ) !mjk
-!$omp end parallel sections
-
- if(dual_res) then
- call ensemble_forward_model_ad_dual_res(wbundle_c,grad%aens(1,:,:),jj)
- else
- call ensemble_forward_model_ad(wbundle_c,grad%aens(1,:,:),jj)
- end if
-
-end do
-
-call gsi_bundledestroy(wbundle_c,istatus)
-if (istatus/=0) then
- write(6,*) trim(myname),': trouble destroying work bundle'
- call stop2(999)
-endif
-
-if (nclouds>0) deallocate(clouds)
-
-! Finalize timer
-!call timer_fnl(trim(myname))
-
-return
-end subroutine ensctl2state_ad
diff --git a/src/gsi/evaljgrad.f90 b/src/gsi/evaljgrad.f90
index 788454034d..e66ca11b8c 100644
--- a/src/gsi/evaljgrad.f90
+++ b/src/gsi/evaljgrad.f90
@@ -73,6 +73,7 @@ subroutine evaljgrad(xhat,fjcost,gradx,lupdfgs,nprt,calledby)
use xhat_vordivmod, only : xhat_vordiv_init, xhat_vordiv_calc, xhat_vordiv_clean
use mpeu_util, only: die
use mpl_allreducemod, only: mpl_allreduce
+use intradmod, only: setrad
implicit none
@@ -195,6 +196,7 @@ subroutine evaljgrad(xhat,fjcost,gradx,lupdfgs,nprt,calledby)
end do
qpred=zero_quad
+call setrad(sval(1))
! Compare obs to solution and transpose back to grid (H^T R^{-1} H)
call intjo(rval,qpred,sval,sbias)
diff --git a/src/gsi/general_commvars_mod.f90 b/src/gsi/general_commvars_mod.f90
index daf182fbdd..f171850373 100644
--- a/src/gsi/general_commvars_mod.f90
+++ b/src/gsi/general_commvars_mod.f90
@@ -19,8 +19,8 @@ module general_commvars_mod
! def s2g_raf - used for subdomain to horizontal grid transfers of full control vector with motley variables
! def s2g_cv - used in bkerror.f90 (full control vector without motley variables)
! def s2g2 - used in getprs.f90
-! def s2g4 - used in get_derivatives2.f90
-! def s1g4 - used in get_derivatives2.f90 (uv versions)
+! def s2g4 - used in get_derivatives2.f90
+! def s1g4 - used in get_derivatives2.f90
! def s2guv - used in getuv.f90
! def s2g_d - used in get_derivatives.f90
! def g1 - used in get_derivatives.f90
@@ -255,7 +255,8 @@ subroutine init_general_commvars
num_fields=3*nsig+1
call general_sub2grid_create_info(g33p1,inner_vars,nlat,nlon,nsig,num_fields,regional,s_ref=s2g_raf)
-! create general_sub2grid structure variable s2g4, which is used in get_derivatives2.f90
+! create general_sub2grid structure variable s2g4, which is used in
+! get_derivatives2.f90
num_fields=2*nsig+1
inner_vars=2
@@ -515,7 +516,7 @@ subroutine fill_ns(grid_in,grid_out)
sumn=sumn+grid_in(i,1)
sums=sums+grid_in(i,nlatm2)
end do
- rnlon=one/float(nlon)
+ rnlon=one/real(nlon,r_kind)
sumn=sumn*rnlon
sums=sums*rnlon
@@ -620,7 +621,7 @@ subroutine fill2_ns(grid_in,grid_out,nlat,nlon)
sumn=sumn+grid_in(i,1)
sums=sums+grid_in(i,nlatm2)
end do
- rnlon=one/float(nlon)
+ rnlon=one/real(nlon,r_kind)
sumn=sumn*rnlon
sums=sums*rnlon
@@ -732,10 +733,10 @@ subroutine filluv_ns(gridu_in,gridv_in,gridu_out,gridv_out)
polsu=polsu+grid(i,2 )*coslon(i)+grid2(i,2 )*sinlon(i)
polsv=polsv+grid(i,2 )*sinlon(i)-grid2(i,2 )*coslon(i)
end do
- polnu=polnu/float(nlon)
- polnv=polnv/float(nlon)
- polsu=polsu/float(nlon)
- polsv=polsv/float(nlon)
+ polnu=polnu/real(nlon,r_kind)
+ polnv=polnv/real(nlon,r_kind)
+ polsu=polsu/real(nlon,r_kind)
+ polsv=polsv/real(nlon,r_kind)
do i=1,nlon
grid (i,nlat)= polnu*coslon(i)+polnv*sinlon(i)
grid2(i,nlat)=-polnu*sinlon(i)+polnv*coslon(i)
@@ -845,10 +846,10 @@ subroutine filluv2_ns(gridu_in,gridv_in,gridu_out,gridv_out,nlat,nlon,sinlon,cos
polsu=polsu+grid(i,2 )*coslon(i)+grid2(i,2 )*sinlon(i)
polsv=polsv+grid(i,2 )*sinlon(i)-grid2(i,2 )*coslon(i)
end do
- polnu=polnu/float(nlon)
- polnv=polnv/float(nlon)
- polsu=polsu/float(nlon)
- polsv=polsv/float(nlon)
+ polnu=polnu/real(nlon,r_kind)
+ polnv=polnv/real(nlon,r_kind)
+ polsu=polsu/real(nlon,r_kind)
+ polsv=polsv/real(nlon,r_kind)
do i=1,nlon
grid (i,nlat)= polnu*coslon(i)+polnv*sinlon(i)
grid2(i,nlat)=-polnu*sinlon(i)+polnv*coslon(i)
diff --git a/src/gsi/general_read_fv3atm.f90 b/src/gsi/general_read_fv3atm.f90
index 3d2646fbbb..d3fcfc1b6c 100644
--- a/src/gsi/general_read_fv3atm.f90
+++ b/src/gsi/general_read_fv3atm.f90
@@ -152,7 +152,8 @@ subroutine general_read_fv3atm_nems(grd,sp_a,filename,uvflag,vordivflag,zflag, &
call stop2(101)
endif
- fhour = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
odate(3) = idate(3) !day
@@ -255,6 +256,7 @@ subroutine general_read_fv3atm_nems(grd,sp_a,filename,uvflag,vordivflag,zflag, &
call stop2(999)
endif
istatus=0
+ istatus1=0
call gsi_bundlegetpointer(gfs_bundle,'ps',g_ps ,ier);istatus = istatus + ier
call gsi_bundlegetpointer(gfs_bundle,'q' ,g_q ,ier);istatus = istatus + ier
call gsi_bundlegetpointer(gfs_bundle,'oz',g_oz ,ier);istatus = istatus + ier
diff --git a/src/gsi/general_read_gfsatm.f90 b/src/gsi/general_read_gfsatm.f90
index 39db75db73..2971f27148 100755
--- a/src/gsi/general_read_gfsatm.f90
+++ b/src/gsi/general_read_gfsatm.f90
@@ -411,6 +411,77 @@ subroutine general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
return
end subroutine general_reload2
+
+! 2m reload
+subroutine general_reload_sfc(grd,g_t2m, g_q2m,g_ps,icount,iflag,work)
+! !USES:
+ use kinds, only: r_kind,i_kind
+ use mpimod, only: npe,mpi_comm_world,ierror,mpi_rtype
+ use general_sub2grid_mod, only: sub2grid_info
+
+ implicit none
+! !INPUT PARAMETERS:
+
+ type(sub2grid_info), intent(in ) :: grd
+ integer(i_kind), intent(inout) :: icount
+ integer(i_kind),dimension(npe), intent(inout) :: iflag
+ real(r_kind),dimension(grd%itotsub),intent(in ) :: work
+
+! !OUTPUT PARAMETERS:
+
+ real(r_kind),dimension(grd%lat2,grd%lon2), intent( out) :: g_t2m,&
+ g_q2m, g_ps
+
+! !DESCRIPTION: version of general_reload, for 2m variables.
+!
+! !REVISION HISTORY:
+! 2023-03-2 Draper
+!-------------------------------------------------------------------------
+
+ integer(i_kind) i,j,ij,k
+ real(r_kind),dimension(grd%lat2*grd%lon2,npe):: sub
+
+ call mpi_alltoallv(work,grd%sendcounts_s,grd%sdispls_s,mpi_rtype,&
+ sub,grd%recvcounts_s,grd%rdispls_s,mpi_rtype,&
+ mpi_comm_world,ierror)
+
+!$omp parallel do schedule(dynamic,1) private(k,i,j,ij)
+
+ do k=1,icount
+ if ( iflag(k) == 2 ) then
+ ij=0
+ do j=1,grd%lon2
+ do i=1,grd%lat2
+ ij=ij+1
+ g_t2m(i,j)=sub(ij,k)
+ enddo
+ enddo
+ elseif ( iflag(k) == 3 ) then
+ ij=0
+ do j=1,grd%lon2
+ do i=1,grd%lat2
+ ij=ij+1
+ g_q2m(i,j)=sub(ij,k)
+ enddo
+ enddo
+ elseif ( iflag(k) == 4 ) then
+ ij=0
+ do j=1,grd%lon2
+ do i=1,grd%lat2
+ ij=ij+1
+ g_ps(i,j)=sub(ij,k)
+ enddo
+ enddo
+ endif
+ enddo ! do k=1,icount
+
+ icount=0
+ iflag=0
+
+ return
+
+end subroutine general_reload_sfc
+
end module gfsreadmod
subroutine general_read_gfsatm(grd,sp_a,sp_b,filename,uvflag,vordivflag,zflag, &
@@ -431,6 +502,7 @@ subroutine general_read_gfsatm(grd,sp_a,sp_b,filename,uvflag,vordivflag,zflag, &
! 2014-11-30 todling - genelize interface to handle bundle instead of fields;
! internal code should be generalized
! 2014-12-03 derber - introduce vordivflag, zflag and optimize routines
+! 2023-03-23 draper - added option to read sfc files (for 2m variables)
!
! input argument list:
! grd - structure variable containing information about grid
@@ -1155,7 +1227,8 @@ subroutine general_read_gfsatm_nems(grd,sp_a,filename,uvflag,vordivflag,zflag, &
enddo
if (mype==0) write(6,*) trim(my_name), ' has_cf = ', has_cf
- fhour = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
odate(3) = idate(3) !day
@@ -1892,7 +1965,7 @@ subroutine general_read_gfsatm_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
use gsi_bundlemod, only: gsi_bundlegetpointer
use module_ncio, only: Dataset, Variable, Dimension, open_dataset,&
close_dataset, get_dim, read_vardata,get_idate_from_time_units
- use gfsreadmod, only: general_reload
+ use gfsreadmod, only: general_reload, general_reload_sfc
implicit none
@@ -1910,6 +1983,7 @@ subroutine general_read_gfsatm_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
real(r_kind),pointer,dimension(:,:) :: ptr2d
real(r_kind),pointer,dimension(:,:,:) :: ptr3d
real(r_kind),pointer,dimension(:,:) :: g_ps
+ real(r_kind),pointer,dimension(:,:) :: g_t2m, g_q2m
real(r_kind),pointer,dimension(:,:,:) :: g_vor,g_div,&
g_cwmr,g_q,g_oz,g_tv
@@ -1942,10 +2016,9 @@ subroutine general_read_gfsatm_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
logical :: procuse,diff_res,eqspace
type(egrid2agrid_parm) :: p_high
logical,dimension(1) :: vector
- type(Dataset) :: atmges
+ type(Dataset) :: filges
type(Dimension) :: ncdim
-
-
+ logical :: read_2m, read_z
!******************************************************************************
! Initialize variables used below
@@ -1959,6 +2032,19 @@ subroutine general_read_gfsatm_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
mype_use=-1
icount=0
procuse=.false.
+
+ if (filename(1:3) == 'sfc') then
+ read_2m = .true.
+ read_z = .false.
+ if ( mype == 0 ) write(6,* ) &
+ trim(my_name), ': reading 2m variables from ', trim(filename)
+ else
+ read_2m = .false.
+ read_z = zflag
+ if ( mype == 0 ) write(6,* ) &
+ trim(my_name), ': reading atmos variables from ', trim(filename)
+ endif
+
if ( mype == 0 ) procuse = .true.
do i=1,npe
if ( grd%recvcounts_s(i-1) > 0 ) then
@@ -1992,23 +2078,24 @@ subroutine general_read_gfsatm_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
if ( procuse ) then
- atmges = open_dataset(filename, paropen=.true., mpicomm=mpi_comm_read)
+ filges = open_dataset(filename, paropen=.true., mpicomm=mpi_comm_read)
! get dimension sizes
- ncdim = get_dim(atmges, 'grid_xt'); lonb = ncdim%len
- ncdim = get_dim(atmges, 'grid_yt'); latb = ncdim%len
- ncdim = get_dim(atmges, 'pfull'); levs = ncdim%len
+ ncdim = get_dim(filges, 'grid_xt'); lonb = ncdim%len
+ ncdim = get_dim(filges, 'grid_yt'); latb = ncdim%len
+ if (.not. read_2m) &
+ ncdim = get_dim(filges, 'pfull'); levs = ncdim%len
! get time information
- idate = get_idate_from_time_units(atmges)
+ idate = get_idate_from_time_units(filges)
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
odate(3) = idate(3) !day
odate(4) = idate(1) !year
- call read_vardata(atmges, 'time', fhour) ! might need to change this to attribute later
+ call read_vardata(filges, 'time', fhour) ! might need to change this to attribute later
! depends on model changes from
! Jeff Whitaker
- fhour = float(nint(fhour))
+ fhour = real(nint(fhour),r_kind)
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
@@ -2030,11 +2117,13 @@ subroutine general_read_gfsatm_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
trim(my_name),grd%nlon,lonb
!call stop2(101)
endif
- if ( levs /= grd%nsig ) then
- if ( mype == 0 ) write(6, &
- '(a,'': inconsistent spatial dimension nsig = '',i4,tr1,''levs = '',i4)') &
- trim(my_name),grd%nsig,levs
- call stop2(101)
+ if (.not. read_2m) then
+ if ( levs /= grd%nsig ) then
+ if ( mype == 0 ) write(6, &
+ '(a,'': inconsistent spatial dimension nsig = '',i4,tr1,''levs = '',i4)') &
+ trim(my_name),grd%nsig,levs
+ call stop2(101)
+ endif
endif
allocate( spec_vor(sp_a%nc), spec_div(sp_a%nc) )
@@ -2047,8 +2136,8 @@ subroutine general_read_gfsatm_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
allocate(rwork3d1(lonb,latb,1))
allocate(rwork2d(lonb,latb))
allocate(rlats(latb+2),rlons(lonb),clons(lonb),slons(lonb))
- call read_vardata(atmges, 'grid_xt', rlons_tmp)
- call read_vardata(atmges, 'grid_yt', rlats_tmp)
+ call read_vardata(filges, 'grid_xt', rlons_tmp)
+ call read_vardata(filges, 'grid_yt', rlats_tmp)
do j=1,latb
rlats(latb+2-j)=deg2rad*rlats_tmp(j)
end do
@@ -2073,57 +2162,73 @@ subroutine general_read_gfsatm_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
endif ! if ( procuse )
! Get pointer to relevant variables (this should be made flexible and general)
- iredundant=0
- call gsi_bundlegetpointer(gfs_bundle,'sf',g_div ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- call gsi_bundlegetpointer(gfs_bundle,'div',g_div ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- if ( iredundant==2 ) then
- if ( mype == 0 ) then
- write(6,*) 'general_read_gfsatm_nems: ERROR'
- write(6,*) 'cannot handle having both sf and div'
- write(6,*) 'Aborting ... '
- endif
- call stop2(999)
- endif
- iredundant=0
- call gsi_bundlegetpointer(gfs_bundle,'vp',g_vor ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- call gsi_bundlegetpointer(gfs_bundle,'vor',g_vor ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- if ( iredundant==2 ) then
- if ( mype == 0 ) then
- write(6,*) 'general_read_gfsatm_nems: ERROR'
- write(6,*) 'cannot handle having both vp and vor'
- write(6,*) 'Aborting ... '
- endif
- call stop2(999)
- endif
- iredundant=0
- call gsi_bundlegetpointer(gfs_bundle,'t' ,g_tv ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- call gsi_bundlegetpointer(gfs_bundle,'tv',g_tv ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- if ( iredundant==2 ) then
- if ( mype == 0 ) then
- write(6,*) 'general_read_gfsatm_nems: ERROR'
- write(6,*) 'cannot handle having both t and tv'
- write(6,*) 'Aborting ... '
- endif
- call stop2(999)
- endif
- istatus=0
- call gsi_bundlegetpointer(gfs_bundle,'ps',g_ps ,ier);istatus=istatus+ier
- call gsi_bundlegetpointer(gfs_bundle,'q' ,g_q ,ier);istatus=istatus+ier
- call gsi_bundlegetpointer(gfs_bundle,'oz',g_oz ,ier);istatus=istatus+ier
- call gsi_bundlegetpointer(gfs_bundle,'cw',g_cwmr,ier);istatus=istatus+ier
- if ( istatus /= 0 ) then
- if ( mype == 0 ) then
- write(6,*) 'general_read_gfsatm_nems: ERROR'
- write(6,*) 'Missing some of the required fields'
- write(6,*) 'Aborting ... '
- endif
- call stop2(999)
+ if (.not. read_2m) then
+ iredundant=0
+ call gsi_bundlegetpointer(gfs_bundle,'sf',g_div ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ call gsi_bundlegetpointer(gfs_bundle,'div',g_div ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ if ( iredundant==2 ) then
+ if ( mype == 0 ) then
+ write(6,*) 'general_read_gfsatm_nc: ERROR'
+ write(6,*) 'cannot handle having both sf and div'
+ write(6,*) 'Aborting ... '
+ endif
+ call stop2(999)
+ endif
+ iredundant=0
+ call gsi_bundlegetpointer(gfs_bundle,'vp',g_vor ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ call gsi_bundlegetpointer(gfs_bundle,'vor',g_vor ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ if ( iredundant==2 ) then
+ if ( mype == 0 ) then
+ write(6,*) 'general_read_gfsatm_nc: ERROR'
+ write(6,*) 'cannot handle having both vp and vor'
+ write(6,*) 'Aborting ... '
+ endif
+ call stop2(999)
+ endif
+ iredundant=0
+ call gsi_bundlegetpointer(gfs_bundle,'t' ,g_tv ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ call gsi_bundlegetpointer(gfs_bundle,'tv',g_tv ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ if ( iredundant==2 ) then
+ if ( mype == 0 ) then
+ write(6,*) 'general_read_gfsatm_nc: ERROR'
+ write(6,*) 'cannot handle having both t and tv'
+ write(6,*) 'Aborting ... '
+ endif
+ call stop2(999)
+ endif
+
+ istatus=0
+ call gsi_bundlegetpointer(gfs_bundle,'ps',g_ps ,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(gfs_bundle,'q' ,g_q ,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(gfs_bundle,'oz',g_oz ,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(gfs_bundle,'cw',g_cwmr,ier);istatus=istatus+ier
+ if ( istatus /= 0 ) then
+ if ( mype == 0 ) then
+ write(6,*) 'general_read_gfsatm_nc: ERROR'
+ write(6,*) 'Missing some of the required fields'
+ write(6,*) 'Aborting ... '
+ endif
+ call stop2(999)
+ endif
+ else ! read 2m vars
+ istatus=0
+ call gsi_bundlegetpointer(gfs_bundle,'t2m',g_t2m ,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(gfs_bundle,'q2m',g_q2m ,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(gfs_bundle,'ps',g_ps ,ier);istatus=istatus+ier
+ if ( istatus /= 0 ) then
+ if ( mype == 0 ) then
+ write(6,*) 'general_read_gfsatm_nc: ERROR'
+ write(6,*) 'Missing 2m required variables'
+ write(6,*) 'Aborting ... '
+ endif
+ call stop2(999)
+ endif
endif
allocate(g_u(grd%lat2,grd%lon2,grd%nsig),g_v(grd%lat2,grd%lon2,grd%nsig))
allocate(g_z(grd%lat2,grd%lon2))
@@ -2135,8 +2240,8 @@ subroutine general_read_gfsatm_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
! Once on the grid, fields need to be scattered from the full domain to
! sub-domains.
- ! Only read Terrain when zflag is true.
- if ( zflag ) then
+ ! Only read Terrain when read_z is true.
+ if ( read_z ) then
icount=icount+1
iflag(icount)=1
@@ -2145,7 +2250,7 @@ subroutine general_read_gfsatm_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
! Terrain: spectral --> grid transform, scatter to all mpi tasks
if (mype==mype_use(icount)) then
! read hs
- call read_vardata(atmges, 'hgtsfc', rwork2d)
+ call read_vardata(filges, 'hgtsfc', rwork2d)
if ( diff_res ) then
grid_b=rwork2d
vector(1)=.false.
@@ -2161,415 +2266,498 @@ subroutine general_read_gfsatm_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
call general_fill_ns(grd,grid,work)
endif
endif
- if ( icount == icm ) then
+ if ( icount == icm ) then
call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
icount,iflag,ilev,work,uvflag,vordivflag)
endif
endif
- icount=icount+1
- iflag(icount)=2
- ilev(icount)=1
+ if (.not. read_2m) then
+
+ icount=icount+1
+ iflag(icount)=2
+ ilev(icount)=1
+
+ ! Surface pressure: same procedure as terrain
+ if (mype==mype_use(icount)) then
+ ! read ps
+ call read_vardata(filges, 'pressfc', rwork2d)
+ rwork2d = r0_001*rwork2d ! convert Pa to cb
+ if ( diff_res ) then
+ vector(1)=.false.
+ grid_b=rwork2d
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork2d
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
+ icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+
+ ! Thermodynamic variable: s-->g transform, communicate to all tasks
+ ! For multilevel fields, each task handles a given level. Periodic
+ ! mpi_alltoallv calls communicate the grids to all mpi tasks.
+ ! Finally, the grids are loaded into guess arrays used later in the
+ ! code.
+
+ do k=1,nlevs
+
+ icount=icount+1
+ iflag(icount)=3
+ ilev(icount)=k
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'spfh', rwork3d1, nslice=kr, slicedim=3)
+ call read_vardata(filges, 'tmp', rwork3d0, nslice=kr, slicedim=3)
+ rwork2d = rwork3d0(:,:,1) * (one+fv*rwork3d1(:,:,1))
+ if ( diff_res ) then
+ grid_b=rwork2d
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork2d
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
+ icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ end do
+
+ if ( vordivflag .or. .not. uvflag ) then
+ do k=1,nlevs
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+ icount=icount+1
+ iflag(icount)=4
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
+ call read_vardata(filges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
+ ! Vorticity
+ ! Convert grid u,v to div and vor
+ if ( diff_res ) then
+ grid_b = rwork3d0(:,:,1)
+ grid_b2 = rwork3d1(:,:,1)
+ vector(1)=.true.
+ call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ do j=1,grd%nlon
+ do i=2,grd%nlat-1
+ grid(j,grd%nlat-i)=grid2(i,j,1)
+ enddo
+ enddo
+ call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work_v(kk)=grid2(i,j,1)
+ enddo
+ do j=1,grd%nlon
+ do i=2,grd%nlat-1
+ grid_v(j,grd%nlat-i)=grid2(i,j,1)
+ enddo
+ enddo
+ else
+ grid = rwork3d0(:,:,1)
+ grid_v = rwork3d1(:,:,1)
+ call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
+ endif
+ allocate( grid_vor(grd%nlon,nlatm2))
+ call general_sptez_v(sp_a,spec_div,spec_vor,grid,grid_v,-1)
+ call general_sptez_s_b(sp_a,sp_a,spec_vor,grid_vor,1)
+ ! Load values into rows for south and north pole
+ call general_fill_ns(grd,grid_vor,work)
+ deallocate(grid_vor)
+ endif
+ if ( icount == icm ) then
+ call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
+ icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+
+ end do
+ do k=1,nlevs
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ icount=icount+1
+ iflag(icount)=5
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
+ call read_vardata(filges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
+ ! Divergence
+ ! Convert grid u,v to div and vor
+ if ( diff_res ) then
+ grid_b = rwork3d0(:,:,1)
+ grid_b2 = rwork3d1(:,:,1)
+ vector(1)=.true.
+ call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ do j=1,grd%nlon
+ do i=2,grd%nlat-1
+ grid(j,grd%nlat-i)=grid2(i,j,1)
+ enddo
+ enddo
+ call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work_v(kk)=grid2(i,j,1)
+ enddo
+ do j=1,grd%nlon
+ do i=2,grd%nlat-1
+ grid_v(j,grd%nlat-i)=grid2(i,j,1)
+ enddo
+ enddo
+ else
+ grid = rwork3d0(:,:,1)
+ grid_v = rwork3d1(:,:,1)
+ call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
+ endif
+ allocate( grid_div(grd%nlon,nlatm2) )
+ call general_sptez_v(sp_a,spec_div,spec_vor,grid,grid_v,-1)
+ call general_sptez_s_b(sp_a,sp_a,spec_div,grid_div,1)
+ ! Load values into rows for south and north pole
+ call general_fill_ns(grd,grid_div,work)
+ deallocate(grid_div)
+ endif
+ if ( icount == icm ) then
+ call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
+ icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+
+ end do
+ endif ! if ( vordivflag .or. .not. uvflag )
+ if ( uvflag ) then
+ do k=1,nlevs
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+ icount=icount+1
+ iflag(icount)=6
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
+ call read_vardata(filges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
+
+ if ( diff_res ) then
+ grid_b = rwork3d0(:,:,1)
+ grid_b2 = rwork3d1(:,:,1)
+ vector(1)=.true.
+ call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid = rwork3d0(:,:,1)
+ grid_v = rwork3d1(:,:,1)
+ call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
+ icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+
+ icount=icount+1
+ iflag(icount)=7
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ ! V
+ call read_vardata(filges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
+ call read_vardata(filges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
+ if ( diff_res ) then
+ grid_b = rwork3d0(:,:,1)
+ grid_b2 = rwork3d1(:,:,1)
+ vector(1)=.true.
+ call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
+ call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid = rwork3d0(:,:,1)
+ grid_v = rwork3d1(:,:,1)
+ ! Note work_v and work are switched because output must be in work.
+ call general_filluv_ns(grd,slons,clons,grid,grid_v,work_v,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
+ icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ end do
+ endif ! if ( uvflag )
+ do k=1,nlevs
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+ icount=icount+1
+ iflag(icount)=8
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ ! Specific humidity
+ call read_vardata(filges, 'spfh', rwork3d0, nslice=kr, slicedim=3)
+ if ( diff_res ) then
+ grid_b=rwork3d0(:,:,1)
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid = rwork3d0(:,:,1)
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
+ icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ end do
+ do k=1,nlevs
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ icount=icount+1
+ iflag(icount)=9
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'o3mr', rwork3d0, nslice=kr, slicedim=3)
+ ! Ozone mixing ratio
+ if ( diff_res ) then
+ grid_b=rwork3d0(:,:,1)
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork3d0(:,:,1)
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
+ icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ end do
+
+ do k=1,nlevs
+ icount=icount+1
+ iflag(icount)=10
+ ilev(icount)=k
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'clwmr', rwork3d0, nslice=kr, slicedim=3)
+ call read_vardata(filges, 'icmr', rwork3d1, nslice=kr, slicedim=3)
+ ! Cloud condensate mixing ratio.
+ rwork2d = rwork3d0(:,:,1)+rwork3d1(:,:,1)
+ if ( diff_res ) then
+ grid_b=rwork2d
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork2d
+ call general_fill_ns(grd,grid,work)
+ endif
+
+ endif
+
+ if ( icount == icm .or. k == nlevs ) then
+ call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
+ icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+
+ enddo ! do k=1,nlevs
+ else ! read_2m
+
+ icount=icount+1
+ iflag(icount)=2
+
+ ! 2m temperature from sfc file
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'tmp2m', rwork2d)
+
+ if ( diff_res ) then
+ vector(1)=.false.
+ grid_b=rwork2d
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork2d
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+
+ icount=icount + 1
+ iflag(icount)=3
+
+ ! 2m humidity from sfc file
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'spfh2m', rwork2d)
+
+ if ( diff_res ) then
+ vector(1)=.false.
+ grid_b=rwork2d
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork2d
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+
+ icount=icount + 1
+ iflag(icount)=4
+
+ if (mype==mype_use(icount)) then
+ ! read ps
+ call read_vardata(filges, 'pressfc', rwork2d)
+ rwork2d = r0_001*rwork2d ! convert Pa to cb
+ if ( diff_res ) then
+ vector(1)=.false.
+ grid_b=rwork2d
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork2d
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+
+ ! not using all procs. doesn't trigger. todo: figure out trigger
+ ! for when reading fewer vars.
+ !if ( icount == icm ) then
+ call general_reload_sfc(grd,g_t2m, g_q2m, g_ps, icount,iflag,work)
+ !endif
+
+ endif ! read_2m
- ! Surface pressure: same procedure as terrain
- if (mype==mype_use(icount)) then
- ! read ps
- call read_vardata(atmges, 'pressfc', rwork2d)
- rwork2d = r0_001*rwork2d ! convert Pa to cb
- if ( diff_res ) then
- vector(1)=.false.
- grid_b=rwork2d
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork2d
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
- icount,iflag,ilev,work,uvflag,vordivflag)
+ if ( procuse ) then
+ if ( diff_res) deallocate(grid_b,grid_b2,grid_c,grid_c2,grid2)
+ call destroy_egrid2agrid(p_high)
+ deallocate(spec_div,spec_vor)
+ deallocate(rwork3d1,rwork3d0,clons,slons)
+ deallocate(rwork2d)
+ deallocate(grid,grid_v)
+ call close_dataset(filges)
endif
+ deallocate(work)
- ! Thermodynamic variable: s-->g transform, communicate to all tasks
- ! For multilevel fields, each task handles a given level. Periodic
- ! mpi_alltoallv calls communicate the grids to all mpi tasks.
- ! Finally, the grids are loaded into guess arrays used later in the
- ! code.
-
- do k=1,nlevs
+ ! Convert dry temperature to virtual temperature
+ !do k=1,grd%nsig
+ ! do j=1,grd%lon2
+ ! do i=1,grd%lat2
+ ! g_tv(i,j,k) = g_tv(i,j,k)*(one+fv*g_q(i,j,k))
+ ! enddo
+ ! enddo
+ !enddo
- icount=icount+1
- iflag(icount)=3
- ilev(icount)=k
- kr = levs+1-k ! netcdf is top to bottom, need to flip
+ ! Load u->div and v->vor slot when uv are used instead
+ if ( .not. read_2m ) then
+ if ( uvflag ) then
+ call gsi_bundlegetpointer(gfs_bundle,'u' ,ptr3d,ier)
+ if ( ier == 0 ) then
+ ptr3d=g_u
+ call gsi_bundlegetpointer(gfs_bundle,'v' ,ptr3d,ier)
+ if ( ier == 0 ) ptr3d=g_v
+ else ! in this case, overload: return u/v in sf/vp slot
+ call gsi_bundlegetpointer(gfs_bundle,'sf' ,ptr3d,ier)
+ if ( ier == 0 ) then
+ ptr3d=g_u
+ call gsi_bundlegetpointer(gfs_bundle,'vp' ,ptr3d,ier)
+ if ( ier == 0 ) ptr3d=g_v
+ endif
+ endif
+ else ! in this case, overload: return u/v in sf/vp slot
+ call gsi_bundlegetpointer(gfs_bundle,'sf' ,ptr3d,ier)
+ if ( ier == 0 ) ptr3d=g_u
+ call gsi_bundlegetpointer(gfs_bundle,'vp' ,ptr3d,ier)
+ if ( ier == 0 ) ptr3d=g_v
+ endif
+ endif ! read_2m
+ if (read_z) then
+ call gsi_bundlegetpointer(gfs_bundle,'z' ,ptr2d,ier)
+ if ( ier == 0 ) ptr2d=g_z
+ endif
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'spfh', rwork3d1, nslice=kr, slicedim=3)
- call read_vardata(atmges, 'tmp', rwork3d0, nslice=kr, slicedim=3)
- rwork2d = rwork3d0(:,:,1) * (one+fv*rwork3d1(:,:,1))
- if ( diff_res ) then
- grid_b=rwork2d
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork2d
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
- icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- end do
+ ! Clean up
+ deallocate(g_z)
+ deallocate(g_u,g_v)
- if ( vordivflag .or. .not. uvflag ) then
- do k=1,nlevs
- kr = levs+1-k ! netcdf is top to bottom, need to flip
- icount=icount+1
- iflag(icount)=4
- ilev(icount)=k
+ ! Print date/time stamp
+ if ( mype == 0 ) then
+ write(6,700) lonb,latb,nlevs,grd%nlon,nlatm2,&
+ fhour,odate,trim(filename)
+700 format('GENERAL_READ_GFSATM_NC: read lonb,latb,levs=',&
+ 3i6,', scatter nlon,nlat=',2i6,', hour=',f6.1,', idate=',4i5,1x,a)
+ endif
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
- call read_vardata(atmges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
- ! Vorticity
- ! Convert grid u,v to div and vor
- if ( diff_res ) then
- grid_b = rwork3d0(:,:,1)
- grid_b2 = rwork3d1(:,:,1)
- vector(1)=.true.
- call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- do j=1,grd%nlon
- do i=2,grd%nlat-1
- grid(j,grd%nlat-i)=grid2(i,j,1)
- enddo
- enddo
- call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work_v(kk)=grid2(i,j,1)
- enddo
- do j=1,grd%nlon
- do i=2,grd%nlat-1
- grid_v(j,grd%nlat-i)=grid2(i,j,1)
- enddo
- enddo
- else
- grid = rwork3d0(:,:,1)
- grid_v = rwork3d1(:,:,1)
- call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
- endif
- allocate( grid_vor(grd%nlon,nlatm2))
- call general_sptez_v(sp_a,spec_div,spec_vor,grid,grid_v,-1)
- call general_sptez_s_b(sp_a,sp_a,spec_vor,grid_vor,1)
- ! Load values into rows for south and north pole
- call general_fill_ns(grd,grid_vor,work)
- deallocate(grid_vor)
- endif
- if ( icount == icm ) then
- call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
- icount,iflag,ilev,work,uvflag,vordivflag)
- endif
+ return
- end do
- do k=1,nlevs
- kr = levs+1-k ! netcdf is top to bottom, need to flip
+end subroutine general_read_gfsatm_nc
- icount=icount+1
- iflag(icount)=5
- ilev(icount)=k
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
- call read_vardata(atmges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
- ! Divergence
- ! Convert grid u,v to div and vor
- if ( diff_res ) then
- grid_b = rwork3d0(:,:,1)
- grid_b2 = rwork3d1(:,:,1)
- vector(1)=.true.
- call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- do j=1,grd%nlon
- do i=2,grd%nlat-1
- grid(j,grd%nlat-i)=grid2(i,j,1)
- enddo
- enddo
- call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work_v(kk)=grid2(i,j,1)
- enddo
- do j=1,grd%nlon
- do i=2,grd%nlat-1
- grid_v(j,grd%nlat-i)=grid2(i,j,1)
- enddo
- enddo
- else
- grid = rwork3d0(:,:,1)
- grid_v = rwork3d1(:,:,1)
- call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
- endif
- allocate( grid_div(grd%nlon,nlatm2) )
- call general_sptez_v(sp_a,spec_div,spec_vor,grid,grid_v,-1)
- call general_sptez_s_b(sp_a,sp_a,spec_div,grid_div,1)
- ! Load values into rows for south and north pole
- call general_fill_ns(grd,grid_div,work)
- deallocate(grid_div)
- endif
- if ( icount == icm ) then
- call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
- icount,iflag,ilev,work,uvflag,vordivflag)
- endif
-
- end do
- endif ! if ( vordivflag .or. .not. uvflag )
- if ( uvflag ) then
- do k=1,nlevs
- kr = levs+1-k ! netcdf is top to bottom, need to flip
- icount=icount+1
- iflag(icount)=6
- ilev(icount)=k
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
- call read_vardata(atmges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
-
- if ( diff_res ) then
- grid_b = rwork3d0(:,:,1)
- grid_b2 = rwork3d1(:,:,1)
- vector(1)=.true.
- call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid = rwork3d0(:,:,1)
- grid_v = rwork3d1(:,:,1)
- call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
- endif
- endif
- if ( icount == icm ) then
- call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
- icount,iflag,ilev,work,uvflag,vordivflag)
- endif
-
- icount=icount+1
- iflag(icount)=7
- ilev(icount)=k
-
- if (mype==mype_use(icount)) then
- ! V
- call read_vardata(atmges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
- call read_vardata(atmges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
- if ( diff_res ) then
- grid_b = rwork3d0(:,:,1)
- grid_b2 = rwork3d1(:,:,1)
- vector(1)=.true.
- call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
- call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid = rwork3d0(:,:,1)
- grid_v = rwork3d1(:,:,1)
- ! Note work_v and work are switched because output must be in work.
- call general_filluv_ns(grd,slons,clons,grid,grid_v,work_v,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
- icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- end do
- endif ! if ( uvflag )
- do k=1,nlevs
- kr = levs+1-k ! netcdf is top to bottom, need to flip
- icount=icount+1
- iflag(icount)=8
- ilev(icount)=k
-
- if (mype==mype_use(icount)) then
- ! Specific humidity
- call read_vardata(atmges, 'spfh', rwork3d0, nslice=kr, slicedim=3)
- if ( diff_res ) then
- grid_b=rwork3d0(:,:,1)
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid = rwork3d0(:,:,1)
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
- icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- end do
- do k=1,nlevs
- kr = levs+1-k ! netcdf is top to bottom, need to flip
-
- icount=icount+1
- iflag(icount)=9
- ilev(icount)=k
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'o3mr', rwork3d0, nslice=kr, slicedim=3)
- ! Ozone mixing ratio
- if ( diff_res ) then
- grid_b=rwork3d0(:,:,1)
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork3d0(:,:,1)
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
- icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- end do
-
- do k=1,nlevs
- icount=icount+1
- iflag(icount)=10
- ilev(icount)=k
- kr = levs+1-k ! netcdf is top to bottom, need to flip
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'clwmr', rwork3d0, nslice=kr, slicedim=3)
- call read_vardata(atmges, 'icmr', rwork3d1, nslice=kr, slicedim=3)
- ! Cloud condensate mixing ratio.
- rwork2d = rwork3d0(:,:,1)+rwork3d1(:,:,1)
- if ( diff_res ) then
- grid_b=rwork2d
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork2d
- call general_fill_ns(grd,grid,work)
- endif
-
- endif
-
- if ( icount == icm .or. k == nlevs ) then
- call general_reload(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz,g_cwmr, &
- icount,iflag,ilev,work,uvflag,vordivflag)
- endif
-
- enddo ! do k=1,nlevs
-
- if ( procuse ) then
- if ( diff_res) deallocate(grid_b,grid_b2,grid_c,grid_c2,grid2)
- call destroy_egrid2agrid(p_high)
- deallocate(spec_div,spec_vor)
- deallocate(rwork3d1,rwork3d0,clons,slons)
- deallocate(rwork2d)
- deallocate(grid,grid_v)
- call close_dataset(atmges)
- endif
- deallocate(work)
-
- ! Convert dry temperature to virtual temperature
- !do k=1,grd%nsig
- ! do j=1,grd%lon2
- ! do i=1,grd%lat2
- ! g_tv(i,j,k) = g_tv(i,j,k)*(one+fv*g_q(i,j,k))
- ! enddo
- ! enddo
- !enddo
-
- ! Load u->div and v->vor slot when uv are used instead
- if ( uvflag ) then
- call gsi_bundlegetpointer(gfs_bundle,'u' ,ptr3d,ier)
- if ( ier == 0 ) then
- ptr3d=g_u
- call gsi_bundlegetpointer(gfs_bundle,'v' ,ptr3d,ier)
- if ( ier == 0 ) ptr3d=g_v
- else ! in this case, overload: return u/v in sf/vp slot
- call gsi_bundlegetpointer(gfs_bundle,'sf' ,ptr3d,ier)
- if ( ier == 0 ) then
- ptr3d=g_u
- call gsi_bundlegetpointer(gfs_bundle,'vp' ,ptr3d,ier)
- if ( ier == 0 ) ptr3d=g_v
- endif
- endif
- else ! in this case, overload: return u/v in sf/vp slot
- call gsi_bundlegetpointer(gfs_bundle,'sf' ,ptr3d,ier)
- if ( ier == 0 ) ptr3d=g_u
- call gsi_bundlegetpointer(gfs_bundle,'vp' ,ptr3d,ier)
- if ( ier == 0 ) ptr3d=g_v
- endif
- if (zflag) then
- call gsi_bundlegetpointer(gfs_bundle,'z' ,ptr2d,ier)
- if ( ier == 0 ) ptr2d=g_z
- endif
-
- ! Clean up
- deallocate(g_z)
- deallocate(g_u,g_v)
-
- ! Print date/time stamp
- if ( mype == 0 ) then
- write(6,700) lonb,latb,nlevs,grd%nlon,nlatm2,&
- fhour,odate,trim(filename)
-700 format('GENERAL_READ_GFSATM_NC: read lonb,latb,levs=',&
- 3i6,', scatter nlon,nlat=',2i6,', hour=',f6.1,', idate=',4i5,1x,a)
- endif
-
- return
-
-end subroutine general_read_gfsatm_nc
subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,zflag, &
gfs_bundle,iret_read)
!$$$ subprogram documentation block
@@ -2618,7 +2806,7 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
use gsi_bundlemod, only: gsi_bundlegetpointer
use module_ncio, only: Dataset, Variable, Dimension, open_dataset,&
close_dataset, get_dim, read_vardata,get_idate_from_time_units
- use gfsreadmod, only: general_reload2
+ use gfsreadmod, only: general_reload2, general_reload_sfc
use ncepnems_io, only: imp_physics
implicit none
@@ -2637,6 +2825,7 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
real(r_kind),pointer,dimension(:,:) :: ptr2d
real(r_kind),pointer,dimension(:,:,:) :: ptr3d
real(r_kind),pointer,dimension(:,:) :: g_ps
+ real(r_kind),pointer,dimension(:,:) :: g_t2m, g_q2m
real(r_kind),pointer,dimension(:,:,:) :: g_vor,g_div,&
g_q,g_oz,g_tv
real(r_kind),pointer,dimension(:,:,:) :: g_ql,g_qi,g_qr,g_qs,g_qg
@@ -2668,8 +2857,9 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
logical :: procuse,diff_res,eqspace
type(egrid2agrid_parm) :: p_high
logical,dimension(1) :: vector
- type(Dataset) :: atmges
+ type(Dataset) :: filges
type(Dimension) :: ncdim
+ logical :: read_2m, read_z
@@ -2685,6 +2875,19 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
mype_use=-1
icount=0
procuse=.false.
+
+ if (filename(1:3) == 'sfc') then
+ read_2m = .true.
+ read_z = .false.
+ if ( mype == 0 ) write(6,* ) &
+ trim(my_name), ': reading 2m variables from ', trim(filename)
+ else
+ read_2m = .false.
+ read_z = zflag
+ if ( mype == 0 ) write(6,* ) &
+ trim(my_name), ': reading atmos variables from ', trim(filename)
+ endif
+
if ( mype == 0 ) procuse = .true.
do i=1,npe
if ( grd%recvcounts_s(i-1) > 0 ) then
@@ -2694,29 +2897,29 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
endif
enddo
icm=icount
- allocate( work(grd%itotsub),work_v(grd%itotsub) )
+ allocate( work(grd%itotsub))
work=zero
- work_v=zero
if ( procuse ) then
- atmges = open_dataset(filename, paropen=.true.)
+ filges = open_dataset(filename, paropen=.true.)
! get dimension sizes
- ncdim = get_dim(atmges, 'grid_xt'); lonb = ncdim%len
- ncdim = get_dim(atmges, 'grid_yt'); latb = ncdim%len
- ncdim = get_dim(atmges, 'pfull'); levs = ncdim%len
+ ncdim = get_dim(filges, 'grid_xt'); lonb = ncdim%len
+ ncdim = get_dim(filges, 'grid_yt'); latb = ncdim%len
+ if (.not. read_2m) &
+ ncdim = get_dim(filges, 'pfull'); levs = ncdim%len
! get time information
- idate = get_idate_from_time_units(atmges)
+ idate = get_idate_from_time_units(filges)
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
odate(3) = idate(3) !day
odate(4) = idate(1) !year
- call read_vardata(atmges, 'time', fhour) ! might need to change this to attribute later
+ call read_vardata(filges, 'time', fhour) ! might need to change this to attribute later
! depends on model changes from
! Jeff Whitaker
- fhour = float(nint(fhour))
+ fhour = real(nint(fhour),r_kind)
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
@@ -2738,11 +2941,13 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
trim(my_name),grd%nlon,lonb
!call stop2(101)
endif
- if ( levs /= grd%nsig ) then
- if ( mype == 0 ) write(6, &
- '(a,'': inconsistent spatial dimension nsig = '',i4,tr1,''levs = '',i4)') &
- trim(my_name),grd%nsig,levs
- call stop2(101)
+ if (.not. read_2m) then
+ if ( levs /= grd%nsig ) then
+ if ( mype == 0 ) write(6, &
+ '(a,'': inconsistent spatial dimension nsig = '',i4,tr1,''levs = '',i4)') &
+ trim(my_name),grd%nsig,levs
+ call stop2(101)
+ endif
endif
allocate( spec_vor(sp_a%nc), spec_div(sp_a%nc) )
@@ -2755,8 +2960,8 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
allocate(rwork3d1(lonb,latb,1))
allocate(rwork2d(lonb,latb))
allocate(rlats(latb+2),rlons(lonb),clons(lonb),slons(lonb))
- call read_vardata(atmges, 'grid_xt', rlons_tmp)
- call read_vardata(atmges, 'grid_yt', rlats_tmp)
+ call read_vardata(filges, 'grid_xt', rlons_tmp)
+ call read_vardata(filges, 'grid_yt', rlats_tmp)
do j=1,latb
rlats(latb+2-j)=deg2rad*rlats_tmp(j)
end do
@@ -2781,63 +2986,79 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
endif ! if ( procuse )
! Get pointer to relevant variables (this should be made flexible and general)
- iredundant=0
- call gsi_bundlegetpointer(gfs_bundle,'sf',g_div ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- call gsi_bundlegetpointer(gfs_bundle,'div',g_div ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- if ( iredundant==2 ) then
- if ( mype == 0 ) then
- write(6,*) 'general_read_gfsatm_allhydro_nc: ERROR'
- write(6,*) 'cannot handle having both sf and div'
- write(6,*) 'Aborting ... '
- endif
- call stop2(999)
- endif
- iredundant=0
- call gsi_bundlegetpointer(gfs_bundle,'vp',g_vor ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- call gsi_bundlegetpointer(gfs_bundle,'vor',g_vor ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- if ( iredundant==2 ) then
- if ( mype == 0 ) then
- write(6,*) 'general_read_gfsatm_allhydro_nc: ERROR'
- write(6,*) 'cannot handle having both vp and vor'
- write(6,*) 'Aborting ... '
- endif
- call stop2(999)
- endif
- iredundant=0
- call gsi_bundlegetpointer(gfs_bundle,'t' ,g_tv ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- call gsi_bundlegetpointer(gfs_bundle,'tv',g_tv ,ier)
- if ( ier == 0 ) iredundant = iredundant + 1
- if ( iredundant==2 ) then
- if ( mype == 0 ) then
- write(6,*) 'general_read_gfsatm_allhydro_nc: ERROR'
- write(6,*) 'cannot handle having both t and tv'
- write(6,*) 'Aborting ... '
- endif
- call stop2(999)
- endif
- istatus=0
- call gsi_bundlegetpointer(gfs_bundle,'ps',g_ps ,ier);istatus=istatus+ier
- call gsi_bundlegetpointer(gfs_bundle,'q' ,g_q ,ier);istatus=istatus+ier
- call gsi_bundlegetpointer(gfs_bundle,'oz',g_oz ,ier);istatus=istatus+ier
-! call gsi_bundlegetpointer(gfs_bundle,'cw',g_cwmr,ier);istatus=istatus+ier
- call gsi_bundlegetpointer(gfs_bundle,'ql',g_ql ,ier);istatus1=istatus1+ier
- call gsi_bundlegetpointer(gfs_bundle,'qi',g_qi ,ier);istatus1=istatus1+ier
- call gsi_bundlegetpointer(gfs_bundle,'qr',g_qr ,ier);istatus1=istatus1+ier
- call gsi_bundlegetpointer(gfs_bundle,'qs',g_qs ,ier);istatus1=istatus1+ier
- call gsi_bundlegetpointer(gfs_bundle,'qg',g_qg ,ier);istatus1=istatus1+ier
-! call gsi_bundlegetpointer(gfs_bundle,'cf',g_cf ,ier);istatus1=istatus1+ier
- if ( istatus1 /= 0 ) then
- if ( mype == 0 ) then
- write(6,*) 'general_read_gfsatm_allhydro_nc: ERROR'
- write(6,*) 'Missing some of the required hydrometeor fields for imp_physics = ', imp_physics
- write(6,*) 'Aborting ... '
- endif
- call stop2(999)
+ if (.not. read_2m) then
+ iredundant=0
+ call gsi_bundlegetpointer(gfs_bundle,'sf',g_div ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ call gsi_bundlegetpointer(gfs_bundle,'div',g_div ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ if ( iredundant==2 ) then
+ if ( mype == 0 ) then
+ write(6,*) 'general_read_gfsatm_allhydro_nc: ERROR'
+ write(6,*) 'cannot handle having both sf and div'
+ write(6,*) 'Aborting ... '
+ endif
+ call stop2(999)
+ endif
+ iredundant=0
+ call gsi_bundlegetpointer(gfs_bundle,'vp',g_vor ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ call gsi_bundlegetpointer(gfs_bundle,'vor',g_vor ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ if ( iredundant==2 ) then
+ if ( mype == 0 ) then
+ write(6,*) 'general_read_gfsatm_allhydro_nc: ERROR'
+ write(6,*) 'cannot handle having both vp and vor'
+ write(6,*) 'Aborting ... '
+ endif
+ call stop2(999)
+ endif
+ iredundant=0
+ call gsi_bundlegetpointer(gfs_bundle,'t' ,g_tv ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ call gsi_bundlegetpointer(gfs_bundle,'tv',g_tv ,ier)
+ if ( ier == 0 ) iredundant = iredundant + 1
+ if ( iredundant==2 ) then
+ if ( mype == 0 ) then
+ write(6,*) 'general_read_gfsatm_allhydro_nc: ERROR'
+ write(6,*) 'cannot handle having both t and tv'
+ write(6,*) 'Aborting ... '
+ endif
+ call stop2(999)
+ endif
+ istatus=0
+ call gsi_bundlegetpointer(gfs_bundle,'ps',g_ps ,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(gfs_bundle,'q' ,g_q ,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(gfs_bundle,'oz',g_oz ,ier);istatus=istatus+ier
+ ! call gsi_bundlegetpointer(gfs_bundle,'cw',g_cwmr,ier);istatus=istatus+ier
+ istatus1=0
+ call gsi_bundlegetpointer(gfs_bundle,'ql',g_ql ,ier);istatus1=istatus1+ier
+ call gsi_bundlegetpointer(gfs_bundle,'qi',g_qi ,ier);istatus1=istatus1+ier
+ call gsi_bundlegetpointer(gfs_bundle,'qr',g_qr ,ier);istatus1=istatus1+ier
+ call gsi_bundlegetpointer(gfs_bundle,'qs',g_qs ,ier);istatus1=istatus1+ier
+ call gsi_bundlegetpointer(gfs_bundle,'qg',g_qg ,ier);istatus1=istatus1+ier
+ ! call gsi_bundlegetpointer(gfs_bundle,'cf',g_cf ,ier);istatus1=istatus1+ier
+ if ( istatus1 /= 0 ) then
+ if ( mype == 0 ) then
+ write(6,*) 'general_read_gfsatm_allhydro_nc: ERROR'
+ write(6,*) 'Missing some of the required hydrometeor fields for imp_physics = ', imp_physics
+ write(6,*) 'Aborting ... '
+ endif
+ call stop2(999)
+ endif
+ else ! read 2m vars
+ istatus=0
+ call gsi_bundlegetpointer(gfs_bundle,'t2m',g_t2m ,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(gfs_bundle,'q2m',g_q2m ,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(gfs_bundle,'ps',g_ps ,ier);istatus=istatus+ier
+ if ( istatus /= 0 ) then
+ if ( mype == 0 ) then
+ write(6,*) 'general_read_gfsatm_allhydro_nc: ERROR'
+ write(6,*) 'Missing 2m required variables'
+ write(6,*) 'Aborting ... '
+ endif
+ call stop2(999)
+ endif
endif
allocate(g_u(grd%lat2,grd%lon2,grd%nsig),g_v(grd%lat2,grd%lon2,grd%nsig))
@@ -2852,7 +3073,7 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
! Only read Terrain when zflag is true.
- if ( zflag ) then
+ if ( read_z ) then
icount=icount+1
iflag(icount)=1
@@ -2861,7 +3082,7 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
! Terrain: spectral --> grid transform, scatter to all mpi tasks
if (mype==mype_use(icount)) then
! read hs
- call read_vardata(atmges, 'hgtsfc', rwork2d)
+ call read_vardata(filges, 'hgtsfc', rwork2d)
if ( diff_res ) then
grid_b=rwork2d
vector(1)=.false.
@@ -2883,465 +3104,470 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
endif
endif
- icount=icount+1
- iflag(icount)=2
- ilev(icount)=1
-
- ! Surface pressure: same procedure as terrain
- if (mype==mype_use(icount)) then
- ! read ps
- call read_vardata(atmges, 'pressfc', rwork2d)
- rwork2d = r0_001*rwork2d ! convert Pa to cb
- if ( diff_res ) then
- vector(1)=.false.
- grid_b=rwork2d
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork2d
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
-
- ! Thermodynamic variable: s-->g transform, communicate to all tasks
- ! For multilevel fields, each task handles a given level. Periodic
- ! mpi_alltoallv calls communicate the grids to all mpi tasks.
- ! Finally, the grids are loaded into guess arrays used later in the
- ! code.
-
- do k=1,nlevs
-
- icount=icount+1
- iflag(icount)=3
- ilev(icount)=k
- kr = levs+1-k ! netcdf is top to bottom, need to flip
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'spfh', rwork3d1, nslice=kr, slicedim=3)
- call read_vardata(atmges, 'tmp', rwork3d0, nslice=kr, slicedim=3)
- rwork2d = rwork3d0(:,:,1) * (one+fv*rwork3d1(:,:,1))
- if ( diff_res ) then
- grid_b=rwork2d
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork2d
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- end do
-
- if ( vordivflag .or. .not. uvflag ) then
- do k=1,nlevs
- kr = levs+1-k ! netcdf is top to bottom, need to flip
- icount=icount+1
- iflag(icount)=4
- ilev(icount)=k
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
- call read_vardata(atmges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
- ! Vorticity
- ! Convert grid u,v to div and vor
- if ( diff_res ) then
- grid_b = rwork3d0(:,:,1)
- grid_b2 = rwork3d1(:,:,1)
- vector(1)=.true.
- call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- do j=1,grd%nlon
- do i=2,grd%nlat-1
- grid(j,grd%nlat-i)=grid2(i,j,1)
- enddo
- enddo
- call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work_v(kk)=grid2(i,j,1)
- enddo
- do j=1,grd%nlon
- do i=2,grd%nlat-1
- grid_v(j,grd%nlat-i)=grid2(i,j,1)
- enddo
- enddo
- else
- grid = rwork3d0(:,:,1)
- grid_v = rwork3d1(:,:,1)
- call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
- endif
- allocate( grid_vor(grd%nlon,nlatm2))
- call general_sptez_v(sp_a,spec_div,spec_vor,grid,grid_v,-1)
- call general_sptez_s_b(sp_a,sp_a,spec_vor,grid_vor,1)
- ! Load values into rows for south and north pole
- call general_fill_ns(grd,grid_vor,work)
- deallocate(grid_vor)
- endif
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- end do
- do k=1,nlevs
- kr = levs+1-k ! netcdf is top to bottom, need to flip
-
- icount=icount+1
- iflag(icount)=5
- ilev(icount)=k
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
- call read_vardata(atmges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
- ! Divergence
- ! Convert grid u,v to div and vor
- if ( diff_res ) then
- grid_b = rwork3d0(:,:,1)
- grid_b2 = rwork3d1(:,:,1)
- vector(1)=.true.
- call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- do j=1,grd%nlon
- do i=2,grd%nlat-1
- grid(j,grd%nlat-i)=grid2(i,j,1)
- enddo
- enddo
- call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work_v(kk)=grid2(i,j,1)
- enddo
- do j=1,grd%nlon
- do i=2,grd%nlat-1
- grid_v(j,grd%nlat-i)=grid2(i,j,1)
- enddo
- enddo
- else
- grid = rwork3d0(:,:,1)
- grid_v = rwork3d1(:,:,1)
- call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
- endif
- allocate( grid_div(grd%nlon,nlatm2) )
- call general_sptez_v(sp_a,spec_div,spec_vor,grid,grid_v,-1)
- call general_sptez_s_b(sp_a,sp_a,spec_div,grid_div,1)
- ! Load values into rows for south and north pole
- call general_fill_ns(grd,grid_div,work)
- deallocate(grid_div)
- endif
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
-
- end do
- endif ! if ( vordivflag .or. .not. uvflag )
-
- if ( uvflag ) then
- do k=1,nlevs
- kr = levs+1-k ! netcdf is top to bottom, need to flip
- icount=icount+1
- iflag(icount)=6
- ilev(icount)=k
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
- call read_vardata(atmges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
-
- if ( diff_res ) then
- grid_b = rwork3d0(:,:,1)
- grid_b2 = rwork3d1(:,:,1)
- vector(1)=.true.
- call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid = rwork3d0(:,:,1)
- grid_v = rwork3d1(:,:,1)
- call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
- endif
- endif
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
-
- icount=icount+1
- iflag(icount)=7
- ilev(icount)=k
-
- if (mype==mype_use(icount)) then
- ! V
- call read_vardata(atmges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
- call read_vardata(atmges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
- if ( diff_res ) then
- grid_b = rwork3d0(:,:,1)
- grid_b2 = rwork3d1(:,:,1)
- vector(1)=.true.
- call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
- call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid = rwork3d0(:,:,1)
- grid_v = rwork3d1(:,:,1)
- ! Note work_v and work are switched because output must be in work.
- call general_filluv_ns(grd,slons,clons,grid,grid_v,work_v,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- end do
- endif ! if ( uvflag )
-
- do k=1,nlevs
- kr = levs+1-k ! netcdf is top to bottom, need to flip
- icount=icount+1
- iflag(icount)=8
- ilev(icount)=k
-
- if (mype==mype_use(icount)) then
- ! Specific humidity
- call read_vardata(atmges, 'spfh', rwork3d0, nslice=kr, slicedim=3)
- if ( diff_res ) then
- grid_b=rwork3d0(:,:,1)
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid = rwork3d0(:,:,1)
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- end do
-
- do k=1,nlevs
- kr = levs+1-k ! netcdf is top to bottom, need to flip
-
- icount=icount+1
- iflag(icount)=9
- ilev(icount)=k
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'o3mr', rwork3d0, nslice=kr, slicedim=3)
- ! Ozone mixing ratio
- if ( diff_res ) then
- grid_b=rwork3d0(:,:,1)
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork3d0(:,:,1)
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- end do
-
- do k=1,nlevs
- icount=icount+1
- iflag(icount)=10
- ilev(icount)=k
- kr = levs+1-k ! netcdf is top to bottom, need to flip
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'clwmr', rwork3d0, nslice=kr, slicedim=3)
- ! Cloud liquid water mixing ratio.
- if ( diff_res ) then
- grid_b=rwork3d0(:,:,1)
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork3d0(:,:,1)
- call general_fill_ns(grd,grid,work)
- endif
- endif
-
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- enddo ! do k=1,nlevs
-
- do k=1,nlevs
- icount=icount+1
- iflag(icount)=11
- ilev(icount)=k
- kr = levs+1-k ! netcdf is top to bottom, need to flip
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'icmr', rwork3d0, nslice=kr, slicedim=3)
- ! Cloud ice water mixing ratio.
- if ( diff_res ) then
- grid_b=rwork3d0(:,:,1)
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork3d0(:,:,1)
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- enddo ! do k=1,nlevs
-
- do k=1,nlevs
- icount=icount+1
- iflag(icount)=12
- ilev(icount)=k
- kr = levs+1-k ! netcdf is top to bottom, need to flip
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'rwmr', rwork3d0, nslice=kr, slicedim=3)
- ! Rain water mixing ratio.
- if ( diff_res ) then
- grid_b=rwork3d0(:,:,1)
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork3d0(:,:,1)
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- enddo ! do k=1,nlevs
-
- do k=1,nlevs
- icount=icount+1
- iflag(icount)=13
- ilev(icount)=k
- kr = levs+1-k ! netcdf is top to bottom, need to flip
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'snmr', rwork3d0, nslice=kr, slicedim=3)
- ! Snow water mixing ratio.
- if ( diff_res ) then
- grid_b=rwork3d0(:,:,1)
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork3d0(:,:,1)
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm ) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- enddo ! do k=1,nlevs
-
- do k=1,nlevs
- icount=icount+1
- iflag(icount)=14
- ilev(icount)=k
- kr = levs+1-k ! netcdf is top to bottom, need to flip
-
- if (mype==mype_use(icount)) then
- call read_vardata(atmges, 'grle', rwork3d0, nslice=kr, slicedim=3)
- ! Graupel mixing ratio.
- if ( diff_res ) then
- grid_b=rwork3d0(:,:,1)
- vector(1)=.false.
- call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
- call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
- do kk=1,grd%itotsub
- i=grd%ltosi_s(kk)
- j=grd%ltosj_s(kk)
- work(kk)=grid2(i,j,1)
- enddo
- else
- grid=rwork3d0(:,:,1)
- call general_fill_ns(grd,grid,work)
- endif
- endif
- if ( icount == icm .or. k==nlevs) then
- call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
- g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
- endif
- enddo ! do k=1,nlevs
+ if (.not. read_2m) then
+
+ allocate( work_v(grd%itotsub) )
+ work_v=zero
+
+ icount=icount+1
+ iflag(icount)=2
+ ilev(icount)=1
+
+ ! Surface pressure: same procedure as terrain
+ if (mype==mype_use(icount)) then
+ ! read ps
+ call read_vardata(filges, 'pressfc', rwork2d)
+ rwork2d = r0_001*rwork2d ! convert Pa to cb
+ if ( diff_res ) then
+ vector(1)=.false.
+ grid_b=rwork2d
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork2d
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+
+ ! Thermodynamic variable: s-->g transform, communicate to all tasks
+ ! For multilevel fields, each task handles a given level. Periodic
+ ! mpi_alltoallv calls communicate the grids to all mpi tasks.
+ ! Finally, the grids are loaded into guess arrays used later in the
+ ! code.
+
+ do k=1,nlevs
+
+ icount=icount+1
+ iflag(icount)=3
+ ilev(icount)=k
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'spfh', rwork3d1, nslice=kr, slicedim=3)
+ call read_vardata(filges, 'tmp', rwork3d0, nslice=kr, slicedim=3)
+ rwork2d = rwork3d0(:,:,1) * (one+fv*rwork3d1(:,:,1))
+ if ( diff_res ) then
+ grid_b=rwork2d
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork2d
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ end do
+
+ if ( vordivflag .or. .not. uvflag ) then
+ do k=1,nlevs
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+ icount=icount+1
+ iflag(icount)=4
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
+ call read_vardata(filges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
+ ! Vorticity
+ ! Convert grid u,v to div and vor
+ if ( diff_res ) then
+ grid_b = rwork3d0(:,:,1)
+ grid_b2 = rwork3d1(:,:,1)
+ vector(1)=.true.
+ call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ do j=1,grd%nlon
+ do i=2,grd%nlat-1
+ grid(j,grd%nlat-i)=grid2(i,j,1)
+ enddo
+ enddo
+ call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work_v(kk)=grid2(i,j,1)
+ enddo
+ do j=1,grd%nlon
+ do i=2,grd%nlat-1
+ grid_v(j,grd%nlat-i)=grid2(i,j,1)
+ enddo
+ enddo
+ else
+ grid = rwork3d0(:,:,1)
+ grid_v = rwork3d1(:,:,1)
+ call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
+ endif
+ allocate( grid_vor(grd%nlon,nlatm2))
+ call general_sptez_v(sp_a,spec_div,spec_vor,grid,grid_v,-1)
+ call general_sptez_s_b(sp_a,sp_a,spec_vor,grid_vor,1)
+ ! Load values into rows for south and north pole
+ call general_fill_ns(grd,grid_vor,work)
+ deallocate(grid_vor)
+ endif
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ end do
+ do k=1,nlevs
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ icount=icount+1
+ iflag(icount)=5
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
+ call read_vardata(filges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
+ ! Divergence
+ ! Convert grid u,v to div and vor
+ if ( diff_res ) then
+ grid_b = rwork3d0(:,:,1)
+ grid_b2 = rwork3d1(:,:,1)
+ vector(1)=.true.
+ call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ do j=1,grd%nlon
+ do i=2,grd%nlat-1
+ grid(j,grd%nlat-i)=grid2(i,j,1)
+ enddo
+ enddo
+ call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work_v(kk)=grid2(i,j,1)
+ enddo
+ do j=1,grd%nlon
+ do i=2,grd%nlat-1
+ grid_v(j,grd%nlat-i)=grid2(i,j,1)
+ enddo
+ enddo
+ else
+ grid = rwork3d0(:,:,1)
+ grid_v = rwork3d1(:,:,1)
+ call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
+ endif
+ allocate( grid_div(grd%nlon,nlatm2) )
+ call general_sptez_v(sp_a,spec_div,spec_vor,grid,grid_v,-1)
+ call general_sptez_s_b(sp_a,sp_a,spec_div,grid_div,1)
+ ! Load values into rows for south and north pole
+ call general_fill_ns(grd,grid_div,work)
+ deallocate(grid_div)
+ endif
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+
+ end do
+ endif ! if ( vordivflag .or. .not. uvflag )
+
+ if ( uvflag ) then
+ do k=1,nlevs
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+ icount=icount+1
+ iflag(icount)=6
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
+ call read_vardata(filges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
+
+ if ( diff_res ) then
+ grid_b = rwork3d0(:,:,1)
+ grid_b2 = rwork3d1(:,:,1)
+ vector(1)=.true.
+ call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid = rwork3d0(:,:,1)
+ grid_v = rwork3d1(:,:,1)
+ call general_filluv_ns(grd,slons,clons,grid,grid_v,work,work_v)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+
+ icount=icount+1
+ iflag(icount)=7
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ ! V
+ call read_vardata(filges, 'ugrd', rwork3d0, nslice=kr, slicedim=3)
+ call read_vardata(filges, 'vgrd', rwork3d1, nslice=kr, slicedim=3)
+ if ( diff_res ) then
+ grid_b = rwork3d0(:,:,1)
+ grid_b2 = rwork3d1(:,:,1)
+ vector(1)=.true.
+ call filluv2_ns(grid_b,grid_b2,grid_c(:,:,1),grid_c2(:,:,1),latb+2,lonb,slons,clons)
+ call g_egrid2agrid(p_high,grid_c2,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid = rwork3d0(:,:,1)
+ grid_v = rwork3d1(:,:,1)
+ ! Note work_v and work are switched because output must be in work.
+ call general_filluv_ns(grd,slons,clons,grid,grid_v,work_v,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ end do
+ endif ! if ( uvflag )
+
+ do k=1,nlevs
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+ icount=icount+1
+ iflag(icount)=8
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ ! Specific humidity
+ call read_vardata(filges, 'spfh', rwork3d0, nslice=kr, slicedim=3)
+ if ( diff_res ) then
+ grid_b=rwork3d0(:,:,1)
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid = rwork3d0(:,:,1)
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ end do
+
+ do k=1,nlevs
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ icount=icount+1
+ iflag(icount)=9
+ ilev(icount)=k
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'o3mr', rwork3d0, nslice=kr, slicedim=3)
+ ! Ozone mixing ratio
+ if ( diff_res ) then
+ grid_b=rwork3d0(:,:,1)
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork3d0(:,:,1)
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ end do
+
+ do k=1,nlevs
+ icount=icount+1
+ iflag(icount)=10
+ ilev(icount)=k
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'clwmr', rwork3d0, nslice=kr, slicedim=3)
+ ! Cloud liquid water mixing ratio.
+ if ( diff_res ) then
+ grid_b=rwork3d0(:,:,1)
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork3d0(:,:,1)
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ enddo ! do k=1,nlevs
+
+ do k=1,nlevs
+ icount=icount+1
+ iflag(icount)=11
+ ilev(icount)=k
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'icmr', rwork3d0, nslice=kr, slicedim=3)
+ ! Cloud ice water mixing ratio.
+ if ( diff_res ) then
+ grid_b=rwork3d0(:,:,1)
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork3d0(:,:,1)
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ enddo ! do k=1,nlevs
+
+ do k=1,nlevs
+ icount=icount+1
+ iflag(icount)=12
+ ilev(icount)=k
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'rwmr', rwork3d0, nslice=kr, slicedim=3)
+ ! Rain water mixing ratio.
+ if ( diff_res ) then
+ grid_b=rwork3d0(:,:,1)
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork3d0(:,:,1)
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ enddo ! do k=1,nlevs
+
+ do k=1,nlevs
+ icount=icount+1
+ iflag(icount)=13
+ ilev(icount)=k
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'snmr', rwork3d0, nslice=kr, slicedim=3)
+ ! Snow water mixing ratio.
+ if ( diff_res ) then
+ grid_b=rwork3d0(:,:,1)
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork3d0(:,:,1)
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm ) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ enddo ! do k=1,nlevs
+
+ do k=1,nlevs
+ icount=icount+1
+ iflag(icount)=14
+ ilev(icount)=k
+ kr = levs+1-k ! netcdf is top to bottom, need to flip
+
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'grle', rwork3d0, nslice=kr, slicedim=3)
+ ! Graupel mixing ratio.
+ if ( diff_res ) then
+ grid_b=rwork3d0(:,:,1)
+ vector(1)=.false.
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork3d0(:,:,1)
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+ if ( icount == icm .or. k==nlevs) then
+ call general_reload2(grd,g_z,g_ps,g_tv,g_vor,g_div,g_u,g_v,g_q,g_oz, &
+ g_ql,g_qi,g_qr,g_qs,g_qg,icount,iflag,ilev,work,uvflag,vordivflag)
+ endif
+ enddo ! do k=1,nlevs
! do k=1,nlevs
! icount=icount+1
@@ -3350,7 +3576,7 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
! kr = levs+1-k ! netcdf is top to bottom, need to flip
!
! if (mype==mype_use(icount)) then
-! call read_vardata(atmges, 'cld_amt', rwork3d0, nslice=kr, slicedim=3)
+! call read_vardata(filges, 'cld_amt', rwork3d0, nslice=kr, slicedim=3)
! ! Cloud amount (cloud fraction).
! if ( diff_res ) then
! grid_b=rwork3d0(:,:,1)
@@ -3374,6 +3600,87 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
! endif
! enddo ! do k=1,nlevs
+ else ! read_2m
+
+ icount=icount+1
+ iflag(icount)=2
+
+ ! 2m temperature from sfc file
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'tmp2m', rwork2d)
+
+ if ( diff_res ) then
+ vector(1)=.false.
+ grid_b=rwork2d
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork2d
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+
+ icount=icount + 1
+ iflag(icount)=3
+
+ ! 2m humidity from sfc file
+ if (mype==mype_use(icount)) then
+ call read_vardata(filges, 'spfh2m', rwork2d)
+
+ if ( diff_res ) then
+ vector(1)=.false.
+ grid_b=rwork2d
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork2d
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+
+ icount=icount + 1
+ iflag(icount)=4
+
+ if (mype==mype_use(icount)) then
+ ! read ps
+ call read_vardata(filges, 'pressfc', rwork2d)
+ rwork2d = r0_001*rwork2d ! convert Pa to cb
+ if ( diff_res ) then
+ vector(1)=.false.
+ grid_b=rwork2d
+ call fill2_ns(grid_b,grid_c(:,:,1),latb+2,lonb)
+ call g_egrid2agrid(p_high,grid_c,grid2,1,1,vector)
+ do kk=1,grd%itotsub
+ i=grd%ltosi_s(kk)
+ j=grd%ltosj_s(kk)
+ work(kk)=grid2(i,j,1)
+ enddo
+ else
+ grid=rwork2d
+ call general_fill_ns(grd,grid,work)
+ endif
+ endif
+
+ ! not necessarily using all assigned tasks (fewer vars), so below doesn't trigger.
+ ! todo: figure out what icm should be here.
+ !if ( icount == icm ) then
+ call general_reload_sfc(grd,g_t2m, g_q2m, g_ps, icount,iflag,work)
+ !endif
+
+ endif ! read_2m
+
+
+
if ( procuse ) then
if ( diff_res) deallocate(grid_b,grid_b2,grid_c,grid_c2,grid2)
call destroy_egrid2agrid(p_high)
@@ -3381,9 +3688,10 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
deallocate(rwork3d1,rwork3d0,clons,slons)
deallocate(rwork2d)
deallocate(grid,grid_v)
- call close_dataset(atmges)
+ call close_dataset(filges)
endif
- deallocate(work, work_v)
+ deallocate(work)
+ if (allocated(work_v)) deallocate(work_v)
! Convert dry temperature to virtual temperature
!do k=1,grd%nsig
@@ -3395,27 +3703,29 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
!enddo
! Load u->div and v->vor slot when uv are used instead
- if ( uvflag ) then
- call gsi_bundlegetpointer(gfs_bundle,'u' ,ptr3d,ier)
- if ( ier == 0 ) then
- ptr3d=g_u
- call gsi_bundlegetpointer(gfs_bundle,'v' ,ptr3d,ier)
- if ( ier == 0 ) ptr3d=g_v
- else ! in this case, overload: return u/v in sf/vp slot
- call gsi_bundlegetpointer(gfs_bundle,'sf' ,ptr3d,ier)
- if ( ier == 0 ) then
- ptr3d=g_u
- call gsi_bundlegetpointer(gfs_bundle,'vp' ,ptr3d,ier)
- if ( ier == 0 ) ptr3d=g_v
- endif
- endif
- else ! in this case, overload: return u/v in sf/vp slot
- call gsi_bundlegetpointer(gfs_bundle,'sf' ,ptr3d,ier)
- if ( ier == 0 ) ptr3d=g_u
- call gsi_bundlegetpointer(gfs_bundle,'vp' ,ptr3d,ier)
- if ( ier == 0 ) ptr3d=g_v
- endif
- if (zflag) then
+ if ( .not. read_2m ) then
+ if ( uvflag ) then
+ call gsi_bundlegetpointer(gfs_bundle,'u' ,ptr3d,ier)
+ if ( ier == 0 ) then
+ ptr3d=g_u
+ call gsi_bundlegetpointer(gfs_bundle,'v' ,ptr3d,ier)
+ if ( ier == 0 ) ptr3d=g_v
+ else ! in this case, overload: return u/v in sf/vp slot
+ call gsi_bundlegetpointer(gfs_bundle,'sf' ,ptr3d,ier)
+ if ( ier == 0 ) then
+ ptr3d=g_u
+ call gsi_bundlegetpointer(gfs_bundle,'vp' ,ptr3d,ier)
+ if ( ier == 0 ) ptr3d=g_v
+ endif
+ endif
+ else ! in this case, overload: return u/v in sf/vp slot
+ call gsi_bundlegetpointer(gfs_bundle,'sf' ,ptr3d,ier)
+ if ( ier == 0 ) ptr3d=g_u
+ call gsi_bundlegetpointer(gfs_bundle,'vp' ,ptr3d,ier)
+ if ( ier == 0 ) ptr3d=g_v
+ endif
+ endif !read_2m
+ if (read_z) then
call gsi_bundlegetpointer(gfs_bundle,'z' ,ptr2d,ier)
if ( ier == 0 ) ptr2d=g_z
endif
@@ -3428,7 +3738,7 @@ subroutine general_read_gfsatm_allhydro_nc(grd,sp_a,filename,uvflag,vordivflag,z
if ( mype == 0 ) then
write(6,700) lonb,latb,nlevs,grd%nlon,nlatm2,&
fhour,odate,trim(filename)
-700 format('GENERAL_READ_GFSATM_NC: read lonb,latb,levs=',&
+700 format('GENERAL_READ_GFSATM_ALLHYDRO_NC: read lonb,latb,levs=',&
3i6,', scatter nlon,nlat=',2i6,', hour=',f6.1,', idate=',4i5,1x,a)
endif
@@ -3504,7 +3814,7 @@ subroutine general_fill_ns(grd,grid_in,grid_out)
sumn=sumn+grid_in(i,1)
sums=sums+grid_in(i,nlatm2)
enddo
- rnlon=one/float(grd%nlon)
+ rnlon=one/real(grd%nlon,r_kind)
sumn=sumn*rnlon
sums=sums*rnlon
@@ -3599,10 +3909,10 @@ subroutine general_filluv_ns(grd,slons,clons,gridu_in,gridv_in,gridu_out,gridv_o
polsu=polsu+gridu_in(i,nlatm2)*clons(i)+gridv_in(i,nlatm2)*slons(i)
polsv=polsv+gridu_in(i,nlatm2)*slons(i)-gridv_in(i,nlatm2)*clons(i)
enddo
- polnu=polnu/float(grd%nlon)
- polnv=polnv/float(grd%nlon)
- polsu=polsu/float(grd%nlon)
- polsv=polsv/float(grd%nlon)
+ polnu=polnu/real(grd%nlon,r_kind)
+ polnv=polnv/real(grd%nlon,r_kind)
+ polsu=polsu/real(grd%nlon,r_kind)
+ polsv=polsv/real(grd%nlon,r_kind)
! Transfer local work array to output grid
do k=1,grd%itotsub
@@ -3699,10 +4009,10 @@ subroutine general_fillu_ns(grd,sp,gridu_in,gridv_in,gridu_out)
polsu=polsu+gridu_in(i,nlatm2)*sp%clons(i)+gridv_in(i,nlatm2)*sp%slons(i)
polsv=polsv+gridu_in(i,nlatm2)*sp%slons(i)-gridv_in(i,nlatm2)*sp%clons(i)
enddo
- polnu=polnu/float(grd%nlon)
- polnv=polnv/float(grd%nlon)
- polsu=polsu/float(grd%nlon)
- polsv=polsv/float(grd%nlon)
+ polnu=polnu/real(grd%nlon,r_kind)
+ polnv=polnv/real(grd%nlon,r_kind)
+ polsu=polsu/real(grd%nlon,r_kind)
+ polsv=polsv/real(grd%nlon,r_kind)
! Transfer local work array to output grid
do k=1,grd%itotsub
@@ -3797,10 +4107,10 @@ subroutine general_fillv_ns(grd,sp,gridu_in,gridv_in,gridv_out)
polsu=polsu+gridu_in(i,nlatm2)*sp%clons(i)+gridv_in(i,nlatm2)*sp%slons(i)
polsv=polsv+gridu_in(i,nlatm2)*sp%slons(i)-gridv_in(i,nlatm2)*sp%clons(i)
enddo
- polnu=polnu/float(grd%nlon)
- polnv=polnv/float(grd%nlon)
- polsu=polsu/float(grd%nlon)
- polsv=polsv/float(grd%nlon)
+ polnu=polnu/real(grd%nlon,r_kind)
+ polnv=polnv/real(grd%nlon,r_kind)
+ polsu=polsu/real(grd%nlon,r_kind)
+ polsv=polsv/real(grd%nlon,r_kind)
! Transfer local work array to output grid
do k=1,grd%itotsub
diff --git a/src/gsi/general_read_nemsaero.f90 b/src/gsi/general_read_nemsaero.f90
index 721545bc65..d1e9f525fd 100644
--- a/src/gsi/general_read_nemsaero.f90
+++ b/src/gsi/general_read_nemsaero.f90
@@ -143,7 +143,8 @@ subroutine general_read_nemsaero(grd,sp_a,filename,mype,gfschem_bundle, &
call stop2(101)
end if
- fhour = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
odate(3) = idate(3) !day
diff --git a/src/gsi/general_spectral_transforms.f90 b/src/gsi/general_spectral_transforms.f90
index d4f0959489..76f4c02c42 100644
--- a/src/gsi/general_spectral_transforms.f90
+++ b/src/gsi/general_spectral_transforms.f90
@@ -99,7 +99,7 @@ subroutine general_g2s0_ad(grd,sp,spectral_in,grid_out)
integer(i_kind) i,j,jj
do i=1,sp%nc
- spec_work(i)=spectral_in(i)/float(grd%nlon)
+ spec_work(i)=spectral_in(i)/real(grd%nlon,r_kind)
if(sp%factsml(i))spec_work(i)=zero
end do
do i=2*sp%jcap+3,sp%nc
@@ -277,7 +277,7 @@ subroutine general_s2g0_ad(grd,sp,spectral_out,grid_in)
call general_sptez_s(sp,spec_work,work,-1)
do i=1,sp%nc
- spec_work(i)=spec_work(i)*float(grd%nlon)
+ spec_work(i)=spec_work(i)*real(grd%nlon,r_kind)
end do
do i=2*sp%jcap+3,sp%nc
spec_work(i)=two*spec_work(i)
@@ -368,8 +368,7 @@ subroutine sfilter(grd,sp,filter,grid)
call general_sptez_s(sp,spec_work,work,-1)
- gnlon=float(grd%nlon)
-! gnlon=real(grd%nlon,r_kind)
+ gnlon=real(grd%nlon,r_kind)
do i=1,sp%nc
spec_work(i)=spec_work(i)*gnlon
end do
@@ -522,8 +521,8 @@ subroutine general_uvg2zds_ad(grd,sp,zsp,dsp,ugrd,vgrd)
integer(i_kind) i,j,jj
do i=1,sp%nc
- spcwrk1(i)=dsp(i)/float(grd%nlon)
- spcwrk2(i)=zsp(i)/float(grd%nlon)
+ spcwrk1(i)=dsp(i)/real(grd%nlon,r_kind)
+ spcwrk2(i)=zsp(i)/real(grd%nlon,r_kind)
if(sp%factvml(i))then
spcwrk1(i)=zero
spcwrk2(i)=zero
@@ -866,8 +865,8 @@ subroutine general_zds2uvg_ad(grd,sp,zsp,dsp,ugrd,vgrd)
end do
do i=1,sp%nc
- spcwrk1(i)=spcwrk1(i)*float(grd%nlon)
- spcwrk2(i)=spcwrk2(i)*float(grd%nlon)
+ spcwrk1(i)=spcwrk1(i)*real(grd%nlon,r_kind)
+ spcwrk2(i)=spcwrk2(i)*real(grd%nlon,r_kind)
end do
do i=2*sp%jcap+3,sp%nc
diff --git a/src/gsi/general_sub2grid_mod.f90 b/src/gsi/general_sub2grid_mod.f90
index f0548643bb..2285cab005 100644
--- a/src/gsi/general_sub2grid_mod.f90
+++ b/src/gsi/general_sub2grid_mod.f90
@@ -87,6 +87,7 @@ module general_sub2grid_mod
interface general_sub2grid
module procedure general_sub2grid_r_single_rank11
module procedure general_sub2grid_r_single_rank14
+ module procedure general_sub2grid_r_single_rank13
module procedure general_sub2grid_r_single_rank4
module procedure general_sub2grid_r_double_rank11
module procedure general_sub2grid_r_double_rank14
@@ -97,6 +98,7 @@ module general_sub2grid_mod
module procedure general_grid2sub_r_single_rank11
module procedure general_grid2sub_r_single_rank41
module procedure general_grid2sub_r_single_rank4
+ module procedure general_grid2sub_r_single_rank31
module procedure general_grid2sub_r_double_rank11
module procedure general_grid2sub_r_double_rank41
module procedure general_grid2sub_r_double_rank4
@@ -519,7 +521,7 @@ subroutine get_iuse_pe(npe,nz,iuse_pe)
else
nskip=npe-nz
if(nskip > 0)then
- skip2=float(npe)/float(nskip)
+ skip2=real(npe,r_kind)/real(nskip,r_kind)
point=zero
do i=1,nskip
ipoint=min(max(0,nint(point)),npe)
@@ -876,7 +878,7 @@ subroutine general_deter_subdomain_nolayout(npe,mype,nlat,nlon,regional, &
! Compute number of points on full grid and target number of
! point per mpi task (pe)
npts=nlat*nlon
- anperpe=float(npts)/float(npe)
+ anperpe=real(npts,r_kind)/real(npe,r_kind)
! Start with square subdomains
nrnc=sqrt(anperpe)
@@ -1019,6 +1021,93 @@ subroutine general_sub2grid_r_single_rank14(s,sub_vars,grid_vars)
end subroutine general_sub2grid_r_single_rank14
+ subroutine general_sub2grid_r_single_rank13(s,sub_vars,grid_vars)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: general_sub2grid_r_single_rank4 convert from subdomains to full horizontal grid
+! prgmmr: parrish org: np22 date: 2010-02-11
+!
+! abstract: generalized version of sub2grid--uses only gsi module kinds.
+! All information needed is contained in the structure variable
+! "s", instead of various modules. This allows
+! for easy adaptation for any collection/ordering of variables
+! defined on subdomains, which need to be made available on
+! full horizontal grid for horizontal operations.
+! The structure variable is specified by subroutine general_sub2grid_setup.
+! This version works with single precision (4-byte) real variables.
+! Input sub_vars, the desired arrays on horizontal subdomains, has one
+! halo row, for now, which is filled with zero, since for ensemble use,
+! there is no need for a halo, but is easiest for now to keep it.
+! A later version will have variable number of halo rows, filled with proper values.
+!
+! program history log:
+! 2010-02-11 parrish, initial documentation
+!
+! input argument list:
+! s - structure variable, contains all necessary information for
+! moving this set of subdomain variables sub_vars to
+! the corresponding set of full horizontal grid variables.
+! sub_vars - input grid values in vertical subdomain mode (contains one halo row)
+!
+! output argument list:
+! grid_vars - output grid values in horizontal slab mode.
+!
+! attributes:
+! language: f90
+! machine: ibm RS/6000 SP
+!
+!$$$
+ use mpimod, only: mpi_comm_world,mpi_real4
+ implicit none
+
+ type(sub2grid_info),intent(in ) :: s
+ real(r_single), intent(in ) :: sub_vars(s%lat2*s%lon2*s%num_fields)
+ real(r_single), intent( out) :: grid_vars(s%nlat,s%nlon,s%kbegin_loc:s%kend_alloc)
+
+ real(r_single) :: sub_vars_r4(s%lat2,s%lon2,s%num_fields)
+ real(r_single) :: sub_vars0(s%lat1,s%lon1,s%num_fields)
+ real(r_single) :: work(s%itotsub*(s%kend_alloc-s%kbegin_loc+1))
+ integer(i_kind) iloc,iskip,i,i0,j,j0,k,n,k_in,ilat,jlon,ierror,ioffset
+
+ sub_vars_r4 = reshape(sub_vars,(/s%lat2,s%lon2,s%num_fields/))
+! remove halo row
+!$omp parallel do schedule(dynamic,1) private(k,j,j0,i0,i)
+ do k=1,s%num_fields
+ do j=2,s%lon2-1
+ j0=j-1
+ do i=2,s%lat2-1
+ i0=i-1
+ sub_vars0(i0,j0,k)=sub_vars_r4(i,j,k)
+ end do
+ end do
+ end do
+
+ call mpi_alltoallv(sub_vars0,s%recvcounts,s%rdispls,mpi_real4, &
+ work,s%sendcounts,s%sdispls,mpi_real4,mpi_comm_world,ierror)
+
+
+ k_in=s%kend_loc-s%kbegin_loc+1
+
+! Load grid_vars array in desired order
+!$omp parallel do schedule(dynamic,1) private(k,iskip,iloc,n,i,ilat,jlon,ioffset)
+ do k=s%kbegin_loc,s%kend_loc
+ iskip=0
+ iloc=0
+ do n=1,s%npe
+ if (n/=1) then
+ iskip=iskip+s%ijn(n-1)*k_in
+ end if
+ ioffset=iskip+(k-s%kbegin_loc)*s%ijn(n)
+ do i=1,s%ijn(n)
+ iloc=iloc+1
+ ilat=s%ltosi(iloc)
+ jlon=s%ltosj(iloc)
+ grid_vars(ilat,jlon,k)=work(i + ioffset)
+ end do
+ end do
+ end do
+
+ end subroutine general_sub2grid_r_single_rank13
subroutine general_sub2grid_r_single_rank4(s,sub_vars,grid_vars)
!$$$ subprogram documentation block
! . . . .
@@ -1199,6 +1288,84 @@ subroutine general_grid2sub_r_single_rank41(s,grid_vars,sub_vars)
end subroutine general_grid2sub_r_single_rank41
+ subroutine general_grid2sub_r_single_rank31(s,grid_vars,sub_vars)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: general_sub2grid convert from subdomains to full horizontal grid
+! prgmmr: parrish org: np22 date: 2010-02-11
+!
+! abstract: generalized version of grid2sub--uses only gsi module kinds.
+! All information needed is contained in the structure variable
+! "s", instead of various modules. This allows
+! for easy adaptation for any collection/ordering of variables
+! defined on subdomains, which need to be made available on
+! full horizontal grid for horizontal operations.
+! The structure variable is specified by subroutine general_sub2grid_setup.
+! This version works with single precision (4-byte) real variables.
+! Output sub_vars, the desired arrays on horizontal subdomains, has one
+! halo row, for now, which is filled with zero, since for ensemble use,
+! there is no need for a halo, but is easiest for now to keep it.
+! A later version will have variable number of halo rows, filled with proper values.
+!
+! program history log:
+! 2010-02-11 parrish, initial documentation
+! 2010-03-02 parrish - remove setting halo to zero in output
+! 2014-12-03 derber - make similar optimization changes already in code for
+! double precision.
+!
+! input argument list:
+! s - structure variable, contains all necessary information for
+! moving this set of subdomain variables sub_vars to
+! the corresponding set of full horizontal grid variables.
+! grid_vars - input grid values in horizontal slab mode.
+!
+! output argument list:
+! sub_vars - output grid values in vertical subdomain mode
+!
+! attributes:
+! language: f90
+! machine: ibm RS/6000 SP
+!
+!$$$
+ use constants, only: zero
+ use mpimod, only: mpi_comm_world,mpi_real4
+ implicit none
+
+ type(sub2grid_info),intent(in ) :: s
+ real(r_single), intent(in ) :: grid_vars(s%nlat,s%nlon,s%kbegin_loc:s%kend_alloc)
+ real(r_single), intent( out) :: sub_vars(s%lat2*s%lon2*s%num_fields)
+
+ real(r_single) :: sub_vars_r4(s%lat2,s%lon2,s%num_fields)
+ real(r_single) :: temp(s%itotsub*(s%kend_loc-s%kbegin_loc+1))
+ integer(i_kind) iloc,i,ii,k,n,ilat,jlon,ierror,icount
+ integer(i_kind),dimension(s%npe) ::iskip
+
+! reorganize for eventual distribution to local domains
+ iskip(1)=0
+ do n=2,s%npe
+ iskip(n)=iskip(n-1)+s%ijn_s(n-1)*(s%kend_loc-s%kbegin_loc+1)
+ end do
+!$omp parallel do schedule(dynamic,1) private(n,k,i,jlon,ii,ilat,iloc,icount)
+ do k=s%kbegin_loc,s%kend_loc
+ icount=0
+ do n=1,s%npe
+ iloc=iskip(n)+(k-s%kbegin_loc)*s%ijn_s(n)
+ do i=1,s%ijn_s(n)
+ iloc=iloc+1
+ icount=icount+1
+ ilat=s%ltosi_s(icount)
+ jlon=s%ltosj_s(icount)
+ temp(iloc)=grid_vars(ilat,jlon,k)
+ end do
+ end do
+ end do
+
+
+ call mpi_alltoallv(temp,s%sendcounts_s,s%sdispls_s,mpi_real4, &
+ sub_vars_r4,s%recvcounts_s,s%rdispls_s,mpi_real4,mpi_comm_world,ierror)
+
+ sub_vars = reshape(sub_vars_r4,(/s%lat2*s%lon2*s%num_fields/))
+ end subroutine general_grid2sub_r_single_rank31
subroutine general_grid2sub_r_single_rank4(s,grid_vars,sub_vars)
!$$$ subprogram documentation block
! . . . .
diff --git a/src/gsi/gengrid_vars.f90 b/src/gsi/gengrid_vars.f90
index a2d352c0b3..adbf510313 100644
--- a/src/gsi/gengrid_vars.f90
+++ b/src/gsi/gengrid_vars.f90
@@ -60,13 +60,13 @@ subroutine gengrid_vars
! This is global run, so get global lons, lats, wgtlats, wgtfactlats
! Set local constants
- anlon=float(nlon)
+ anlon=real(nlon,r_kind)
pih=half*pi
dlon=two*pi/anlon
! Load grid lat,lon arrays. rbs2 is used in pcp.
do i=1,nlon
- rlons(i)=float(i-1)*dlon
+ rlons(i)=real(i-1,r_kind)*dlon
coslon(i)=cos(rlons(i))
sinlon(i)=sin(rlons(i))
end do
diff --git a/src/gsi/genqsat.f90 b/src/gsi/genqsat.f90
index ed0eb152e6..bc33187497 100644
--- a/src/gsi/genqsat.f90
+++ b/src/gsi/genqsat.f90
@@ -145,9 +145,9 @@ subroutine genqsat(qsat,tsen,prsl,lat2,lon2,nsig,ice,iderivative)
esw = psat * (tr**xa) * exp(xb*(one-tr))
esi = psat * (tr**xai) * exp(xbi*(one-tr))
w = (tdry - tmix) / (ttp - tmix)
-! es = w * esw + (one-w) * esi
- es = w * psat * (tr**xa) * exp(xb*(one-tr)) &
- + (one-w) * psat * (tr**xai) * exp(xbi*(one-tr))
+ es = w * esw + (one-w) * esi
+! es = w * psat * (tr**xa) * exp(xb*(one-tr)) &
+! + (one-w) * psat * (tr**xai) * exp(xbi*(one-tr))
endif
diff --git a/src/gsi/genstats_gps.f90 b/src/gsi/genstats_gps.f90
index ce90d06f50..576dce5d8c 100644
--- a/src/gsi/genstats_gps.f90
+++ b/src/gsi/genstats_gps.f90
@@ -64,6 +64,15 @@ module m_gpsStats
integer(i_kind) :: idv,iob ! device id and obs index for sorting
real (r_kind) :: elat, elon ! earth lat-lon for redistribution
!real (r_kind) :: dlat, dlon ! earth lat-lon for redistribution
+ !> xuanli
+ real(r_kind),dimension(:),pointer :: tsenges => NULL()
+ real(r_kind),dimension(:),pointer :: tvirges => NULL()
+ real(r_kind),dimension(:),pointer :: sphmges => NULL()
+ real(r_kind),dimension(:),pointer :: hgtlges => NULL()
+ real(r_kind),dimension(:),pointer :: hgtiges => NULL()
+ real(r_kind),dimension(:),pointer :: prslges => NULL()
+ real(r_kind),dimension(:),pointer :: prsiges => NULL()
+ !< xuanli
end type gps_all_ob_type
type gps_all_ob_head
@@ -250,7 +259,7 @@ subroutine genstats_gps(bwork,awork,toss_gps_sub,conv_diagsave,mype)
use obsmod, only: lobsdiagsave,luse_obsdiag
use obsmod, only: binary_diag,netcdf_diag,dirname,ianldate
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim, nc_diag_read_close
use gridmod, only: nsig,regional
use constants, only: tiny_r_kind,half,wgtlim,one,two,zero,five,four
@@ -427,7 +436,10 @@ subroutine genstats_gps(bwork,awork,toss_gps_sub,conv_diagsave,mype)
end do
END DO
if(icnt > 0)then
- nreal =22
+!> xuanli
+! nreal =22
+ nreal =35
+!< xuanli
ioff =nreal
if (lobsdiagsave) nreal=nreal+4*miter+1
if (save_jacobian) then
@@ -760,33 +772,48 @@ subroutine contents_netcdf_diag_
! Observation class
character(7),parameter :: obsclass = ' gps'
- call nc_diag_metadata("Station_ID", gps_allptr%cdiag )
- call nc_diag_metadata("Observation_Class", obsclass )
+ call nc_diag_metadata("Station_ID", gps_allptr%cdiag )
+ call nc_diag_metadata("Observation_Class", obsclass )
obstype = gps_allptr%rdiag(1)
obssubtype = gps_allptr%rdiag(2)
call nc_diag_metadata("Observation_Type", obstype )
call nc_diag_metadata("Observation_Subtype", obssubtype )
- call nc_diag_metadata("Latitude", sngl(gps_allptr%rdiag(3)) )
- call nc_diag_metadata("Longitude", sngl(gps_allptr%rdiag(4)) )
- call nc_diag_metadata("Incremental_Bending_Angle", sngl(gps_allptr%rdiag(5)) )
- call nc_diag_metadata("Pressure", sngl(gps_allptr%rdiag(6)) )
- call nc_diag_metadata("Height", sngl(gps_allptr%rdiag(7)) )
- call nc_diag_metadata("Time", sngl(gps_allptr%rdiag(8)) )
- call nc_diag_metadata("Model_Elevation", sngl(gps_allptr%rdiag(9)) )
- call nc_diag_metadata("Setup_QC_Mark", sngl(gps_allptr%rdiag(10)) )
- call nc_diag_metadata("Prep_Use_Flag", sngl(gps_allptr%rdiag(11)) )
- call nc_diag_metadata("Analysis_Use_Flag", sngl(gps_allptr%rdiag(12)) )
-
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(gps_allptr%rdiag(13)) )
- call nc_diag_metadata("Errinv_Input", sngl(gps_allptr%rdiag(14)) )
- call nc_diag_metadata("Errinv_Adjust", sngl(gps_allptr%rdiag(15)) )
- call nc_diag_metadata("Errinv_Final", sngl(gps_allptr%rdiag(16)) )
- call nc_diag_metadata("Observation", sngl(gps_allptr%rdiag(17)) )
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(gps_allptr%rdiag(17))*sngl(gps_allptr%rdiag(5)) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(gps_allptr%rdiag(17))*sngl(gps_allptr%rdiag(5)) )
- call nc_diag_metadata("GPS_Type", sngl(gps_allptr%rdiag(20)) )
- call nc_diag_metadata("Temperature_at_Obs_Location", sngl(gps_allptr%rdiag(18)) )
- call nc_diag_metadata("Specific_Humidity_at_Obs_Location", sngl(gps_allptr%rdiag(21)) )
+ call nc_diag_metadata_to_single("Latitude", gps_allptr%rdiag(3) )
+ call nc_diag_metadata_to_single("Longitude", gps_allptr%rdiag(4) )
+ call nc_diag_metadata_to_single("Incremental_Bending_Angle", gps_allptr%rdiag(5) )
+ call nc_diag_metadata_to_single("Pressure", gps_allptr%rdiag(6) )
+ call nc_diag_metadata_to_single("Impact_Height", gps_allptr%rdiag(7) )
+ call nc_diag_metadata_to_single("Time", gps_allptr%rdiag(8) )
+ call nc_diag_metadata_to_single("Model_Elevation", gps_allptr%rdiag(9) )
+ call nc_diag_metadata_to_single("Setup_QC_Mark", gps_allptr%rdiag(10) )
+ call nc_diag_metadata_to_single("Prep_Use_Flag", gps_allptr%rdiag(11) )
+ call nc_diag_metadata_to_single("Analysis_Use_Flag", gps_allptr%rdiag(12) )
+
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt", gps_allptr%rdiag(13) )
+ call nc_diag_metadata_to_single("Errinv_Input", gps_allptr%rdiag(14) )
+ call nc_diag_metadata_to_single("Errinv_Adjust", gps_allptr%rdiag(15) )
+ call nc_diag_metadata_to_single("Errinv_Final", gps_allptr%rdiag(16) )
+ call nc_diag_metadata_to_single("Observation", gps_allptr%rdiag(17) )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted", gps_allptr%rdiag(17),gps_allptr%rdiag(5),"*")
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted",gps_allptr%rdiag(17),gps_allptr%rdiag(5),"*")
+ call nc_diag_metadata_to_single("GPS_Type", gps_allptr%rdiag(20) )
+ call nc_diag_metadata_to_single("Temperature_at_Obs_Location", gps_allptr%rdiag(18) )
+ call nc_diag_metadata_to_single("Specific_Humidity_at_Obs_Location",gps_allptr%rdiag(21) )
+
+ call nc_diag_metadata_to_single("impact_parameter", gps_allptr%rdiag(23))
+ call nc_diag_metadata_to_single("pccf", gps_allptr%rdiag(24))
+ call nc_diag_metadata_to_single("reference_sat_id", gps_allptr%rdiag(25))
+ call nc_diag_metadata_to_single("earth_radius_of_curvature", gps_allptr%rdiag(26))
+ call nc_diag_metadata_to_single("geoid_height_above_reference_ellipsoid", gps_allptr%rdiag(27))
+ call nc_diag_metadata_to_single("qfro", gps_allptr%rdiag(28))
+ call nc_diag_metadata_to_single("ascending_flag", gps_allptr%rdiag(29))
+ call nc_diag_metadata_to_single("sensor_azimuth_angle", gps_allptr%rdiag(30))
+ call nc_diag_metadata_to_single("sat_constellation", gps_allptr%rdiag(31))
+ call nc_diag_metadata_to_single("occulting_sat", gps_allptr%rdiag(32))
+ call nc_diag_metadata_to_single("process_center", gps_allptr%rdiag(33))
+ call nc_diag_metadata_to_single("atmospheric_refractivity", gps_allptr%rdiag(34))
+! xuanli output the altitude as height
+ call nc_diag_metadata_to_single("Height", gps_allptr%rdiag(35))
if (save_jacobian) then
call readarray(dhx_dx, gps_allptr%rdiag(ioff+1:nreal))
@@ -794,6 +821,16 @@ subroutine contents_netcdf_diag_
call nc_diag_data2d("Observation_Operator_Jacobian_endind", dhx_dx%end_ind(1:dhx_dx%nind))
call nc_diag_data2d("Observation_Operator_Jacobian_val", real(dhx_dx%val(1:dhx_dx%nnz),r_single))
endif
+!> xuanli
+ call nc_diag_data2d("atmosphere_pressure_coordinate", sngl(gps_allptr%prslges))
+ call nc_diag_data2d("atmosphere_pressure_coordinate_interface", sngl(gps_allptr%prsiges))
+ call nc_diag_data2d("air_temperature", sngl(gps_allptr%tsenges))
+ call nc_diag_data2d("virtual_temperature", sngl(gps_allptr%tvirges))
+ call nc_diag_data2d("specific_humidity", sngl(gps_allptr%sphmges))
+ call nc_diag_data2d("geopotential_height", sngl(gps_allptr%hgtlges))
+ call nc_diag_data2d("geopotential_height_levels", sngl(gps_allptr%hgtiges))
+
+!< xuanli
diff --git a/src/gsi/gesinfo.F90 b/src/gsi/gesinfo.F90
index 792900b628..9d287de414 100644
--- a/src/gsi/gesinfo.F90
+++ b/src/gsi/gesinfo.F90
@@ -62,7 +62,8 @@ subroutine gesinfo
! nfsecondn FCST Secs (i_kind) numerator
! nfsecondd FCST Secs (i_kind) denominator
!
-! %fhour = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+! %fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+! real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
!
! attributes:
! language: f90
@@ -148,7 +149,7 @@ subroutine gesinfo
write(filename,'("sigf",i2.2)')nhr_assimilation
inquire(file=filename,exist=fexist)
if(.not.fexist) then
- write(6,*)' GESINFO: ***ERROR*** ',trim(filename),' NOT AVAILABLE: PROGRAM STOPS'
+ write(6,*)' GESINFO: ***FATAL ERROR*** ',trim(filename),' NOT AVAILABLE: PROGRAM STOPS'
call stop2(99)
stop
end if
@@ -312,8 +313,8 @@ subroutine gesinfo
nfhour, nfminute, nfsecondn, nfsecondd
call stop2(99)
endif
- gfshead%fhour = float(nfhour) + float(nfminute)/r60 + &
- float(nfsecondn)/float(nfsecondd)/r3600
+ gfshead%fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
gfshead%idate(1) = idate(4) !hour
gfshead%idate(3) = idate(3) !day
@@ -339,12 +340,12 @@ subroutine gesinfo
! open the netCDF file
atmges = open_dataset(filename,errcode=iret)
if (iret /=0) then
- write(6,*)'GESINFO: ***ERROR*** ',trim(filename),' NOT AVAILABLE: PROGRAM STOPS'
+ write(6,*)'GESINFO: ***FATAL ERROR*** ',trim(filename),' NOT AVAILABLE: PROGRAM STOPS'
call stop2(99)
endif
sfcges = open_dataset(sfilename,errcode=iret)
if (iret /=0) then
- write(6,*)'GESINFO: ***ERROR*** ',trim(sfilename),' NOT AVAILABLE: PROGRAM STOPS'
+ write(6,*)'GESINFO: ***FATAL ERROR*** ',trim(sfilename),' NOT AVAILABLE: PROGRAM STOPS'
call stop2(99)
endif
! get dimension sizes
@@ -451,7 +452,7 @@ subroutine gesinfo
! Check for consistency with namelist settings
if (gfshead%jcap/=jcap_b.and..not.regional .or. gfshead%levs/=nsig) then
if (gfshead%levs/=nsig) then
- write(6,*)'GESINFO: ***ERROR*** guess levels inconsistent with namelist'
+ write(6,*)'GESINFO: ***FATAL ERROR*** guess levels inconsistent with namelist'
write(6,*)' guess nsig=',gfshead%levs
write(6,*)' namelist nsig=',nsig
fatal = .true.
@@ -466,7 +467,7 @@ subroutine gesinfo
fatal = .false.
else
if ( mype == mype_out ) &
- write(6,*)'GESINFO: ***ERROR*** guess jcap inconsistent with namelist'
+ write(6,*)'GESINFO: ***FATAL ERROR*** guess jcap inconsistent with namelist'
fatal = .true.
endif
if ( mype == mype_out ) &
@@ -551,7 +552,7 @@ subroutine gesinfo
ida(:)=0
jda(:)=0
fha(:)=zero
- fha(2)=-float(int(min_offset/60))
+ fha(2)=-real(int(min_offset/60),r_kind)
fha(3)=-(min_offset+fha(2)*r60)
ida(1:3)=iadate(1:3)
ida(5:6)=iadate(4:5)
@@ -582,7 +583,7 @@ subroutine gesinfo
! Get time offset
call time_4dvar(ianldate,time_offset)
#ifdef RR_CLOUDANALYSIS
- fha(2)=float(int(min_offset/60))
+ fha(2)=real(int(min_offset/60),r_kind)
fha(3)=(min_offset-fha(2)*r60)
time_offset=time_offset+fha(3)/r60
#endif
diff --git a/src/gsi/get_gefs_ensperts_dualres.f90 b/src/gsi/get_gefs_ensperts_dualres.f90
index fa3d0ecbdd..ca5db84a1a 100644
--- a/src/gsi/get_gefs_ensperts_dualres.f90
+++ b/src/gsi/get_gefs_ensperts_dualres.f90
@@ -26,7 +26,7 @@ subroutine get_gefs_ensperts_dualres
!
! get_gefs_ensperts_dualres.f90(182): error #6460: This is not a field name that
! is defined in the encompassing structure. [LAT2]
-! call genqsat(qs,tsen,prsl,grd_ens%lat2,grd_ens%lon2,grd_ens%nsig,ice,iderivative)
+! call genqsat2(qs,tsen,prsl,grd_ens%lat2,grd_ens%lon2,grd_ens%nsig,ice)
! 2014-11-30 todling - partially generalized to handle any control vector
! (GFS hook needs further attention)
! - also, take SST from members of ensemble
@@ -49,10 +49,9 @@ subroutine get_gefs_ensperts_dualres
!$$$ end documentation block
use mpeu_util, only: die
- use gridmod, only: idsl5
use hybrid_ensemble_parameters, only: n_ens,write_ens_sprd,oz_univ_static,ntlevs_ens
use hybrid_ensemble_parameters, only: en_perts,ps_bar,nelen
- use constants,only: zero,zero_single,half,fv,rd_over_cp,one,qcmin
+ use constants,only: zero,zero_single,half,fv,one,qcmin
use mpimod, only: mpi_comm_world,mype,npe
use kinds, only: r_kind,i_kind,r_single
use hybrid_ensemble_parameters, only: grd_ens,q_hyb_ens,limqens
@@ -64,10 +63,12 @@ subroutine get_gefs_ensperts_dualres
use gsi_bundlemod, only: gsi_bundlegetpointer
use gsi_bundlemod, only: gsi_bundledestroy
use gsi_bundlemod, only: gsi_gridcreate
+ use gsi_bundlemod, only : assignment(=)
use gsi_enscouplermod, only: gsi_enscoupler_get_user_nens
use gsi_enscouplermod, only: gsi_enscoupler_create_sub2grid_info
use gsi_enscouplermod, only: gsi_enscoupler_destroy_sub2grid_info
use general_sub2grid_mod, only: sub2grid_info,general_sub2grid_create_info,general_sub2grid_destroy_info
+ use hybrid_ensemble_parameters, only: nsclgrp,sp_ens,global_spectral_filter_sd
implicit none
real(r_kind),pointer,dimension(:,:) :: ps
@@ -76,21 +77,23 @@ subroutine get_gefs_ensperts_dualres
! real(r_kind),dimension(grd_ens%nlat,grd_ens%nlon):: sst_full,dum
real(r_kind),pointer,dimension(:,:,:):: p3
real(r_kind),pointer,dimension(:,:):: x2
- type(gsi_bundle),allocatable,dimension(:) :: en_read
+ type(gsi_bundle),allocatable,dimension(:) :: en_real8
type(gsi_bundle):: en_bar
! type(gsi_grid) :: grid_ens
- real(r_kind) bar_norm,sig_norm,kapr,kap1
+ real(r_kind) bar_norm,sig_norm
! real(r_kind),allocatable,dimension(:,:):: z,sst2
- real(r_kind),allocatable,dimension(:,:,:) :: tsen,prsl,pri,qs
+ real(r_kind),allocatable,dimension(:,:,:) :: tsen,prsl
! integer(i_kind),dimension(grd_ens%nlat,grd_ens%nlon):: idum
- integer(i_kind) istatus,iret,i,ic3,j,k,n,iderivative,im,jm,km,m,ipic
+ integer(i_kind) istatus,iret,i,ic3,j,k,n,im,jm,km,m,ipic
! integer(i_kind) mm1
integer(i_kind) ipc3d(nc3d),ipc2d(nc2d)
integer(i_kind) ier
! integer(i_kind) il,jl
logical ice,hydrometeor
type(sub2grid_info) :: grd_tmp
+ real(r_kind),parameter :: r0_001 = 0.001_r_kind
+
! Create perturbations grid and get variable names from perturbations
if(en_perts(1,1,1)%grid%im/=grd_ens%lat2.or. &
@@ -119,7 +122,7 @@ subroutine get_gefs_ensperts_dualres
im=en_perts(1,1,1)%grid%im
jm=en_perts(1,1,1)%grid%jm
km=en_perts(1,1,1)%grid%km
- bar_norm = one/float(n_ens)
+ bar_norm = one/real(n_ens,r_kind)
sig_norm=sqrt(one/max(one,n_ens-one))
! Create temporary communication information for read ensemble routines
@@ -130,31 +133,24 @@ subroutine get_gefs_ensperts_dualres
if ( istatus /= 0 ) &
call die('get_gefs_ensperts_dualres',': trouble creating en_bar bundle, istatus =',istatus)
- ! Allocate bundle used for reading members
- allocate(en_read(n_ens))
+ ! Allocate bundle used for real*8 version of members
+ allocate(en_real8(n_ens))
do n=1,n_ens
- call gsi_bundlecreate(en_read(n),en_perts(1,1,1)%grid,'ensemble member',istatus,names2d=cvars2d,names3d=cvars3d)
+ call gsi_bundlecreate(en_real8(n),en_perts(1,1,1)%grid,'ensemble member',istatus,names2d=cvars2d,names3d=cvars3d)
if ( istatus /= 0 ) &
- call die('get_gefs_ensperts_dualres',': trouble creating en_read bundle, istatus =',istatus)
+ call die('get_gefs_ensperts_dualres',': trouble creating en_real8 bundle, istatus =',istatus)
end do
+
! allocate(z(im,jm))
! allocate(sst2(im,jm))
! sst2=zero ! for now, sst not used in ensemble perturbations, so if sst array is called for
! then sst part of en_perts will be zero when sst2=zero
-!$omp parallel do schedule(dynamic,1) private(m,n)
- do m=1,ntlevs_ens
- do n=1,n_ens
- en_perts(n,1,m)%valuesr4=zero_single
- end do
- end do
-
-
ntlevs_ens_loop: do m=1,ntlevs_ens
- call gsi_enscoupler_get_user_Nens(grd_tmp,n_ens,m,en_read,iret)
+ call gsi_enscoupler_get_user_Nens(grd_tmp,n_ens,m,en_perts(:,1,m),iret)
! Check read return code. Revert to static B if read error detected
if ( iret /= 0 ) then
@@ -166,65 +162,53 @@ subroutine get_gefs_ensperts_dualres
cycle
endif
+ en_bar%values=zero
+ allocate(tsen(im,jm,km))
if (.not.q_hyb_ens) then !use RH
- kap1=rd_over_cp+one
- kapr=one/rd_over_cp
- do n=1,n_ens
+ allocate(prsl(im,jm,km))
+ end if
+ do n=1,n_ens
+ do i=1,nelen
+ en_real8(n)%values(i)=real(en_perts(n,1,m)%valuesr4(i),r_kind)
+ end do
- call gsi_bundlegetpointer(en_read(n),'ps',ps,ier);istatus=ier
- call gsi_bundlegetpointer(en_read(n),'t' ,tv,ier);istatus=istatus+ier
- call gsi_bundlegetpointer(en_read(n),'q' ,q ,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(en_real8(n),'q' ,q ,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(en_real8(n),'t' ,tv,ier);istatus=istatus+ier
+ call gsi_bundlegetpointer(en_real8(n),'ps',ps,ier);istatus=ier
+! Convert ps to correct units
+ do j=1,jm
+ do i=1,im
+ ps(i,j)=r0_001*ps(i,j)
+ end do
+ end do
+! Convert to real from single and convert tv to virtual temperature
+ do k=1,km
+ do j=1,jm
+ do i=1,im
+! Use following 3 lines for results identical to previous version
+! tv(i,j,k)= tv(i,j,k)*(one+fv*q(i,j,k))
+! q(i,j,k)=max(q(i,j,k),zero)
+! tsen(i,j,k)=tv(i,j,k)/(one+fv*q(i,j,k))
+! Remove following 3 lines for results identical to previous version
+ q(i,j,k)=max(q(i,j,k),zero)
+ tsen(i,j,k)=tv(i,j,k)
+ tv(i,j,k)= tsen(i,j,k)*(one+fv*q(i,j,k))
+ end do
+ end do
+ end do
+ if (.not.q_hyb_ens) then !use RH
+
! Compute RH
! Get 3d pressure field now on interfaces
- allocate(pri(im,jm,km+1))
- call general_getprs_glb(ps,tv,pri)
- allocate(prsl(im,jm,km),tsen(im,jm,km),qs(im,jm,km))
-! Get sensible temperature and 3d layer pressure
- if (idsl5 /= 2) then
-!$omp parallel do schedule(dynamic,1) private(k,j,i)
- do k=1,km
- do j=1,jm
- do i=1,im
- prsl(i,j,k)=((pri(i,j,k)**kap1-pri(i,j,k+1)**kap1)/&
- (kap1*(pri(i,j,k)-pri(i,j,k+1))))**kapr
- tsen(i,j,k)= tv(i,j,k)/(one+fv*max(zero,q(i,j,k)))
- end do
- end do
- end do
- else
-!$omp parallel do schedule(dynamic,1) private(k,j,i)
- do k=1,km
- do j=1,jm
- do i=1,im
- prsl(i,j,k)=(pri(i,j,k)+pri(i,j,k+1))*half
- tsen(i,j,k)= tv(i,j,k)/(one+fv*max(zero,q(i,j,k)))
- end do
- end do
- end do
- end if
- deallocate(pri)
+ call general_getprs_glb(ps,tv,prsl)
ice=.true.
- iderivative=0
- call genqsat(qs,tsen,prsl,im,jm,km,ice,iderivative)
- do k=1,km
- do j=1,jm
- do i=1,im
- q(i,j,k)=q(i,j,k)/qs(i,j,k)
- end do
- end do
- end do
- deallocate(tsen,prsl,qs)
- enddo
- end if
+ call genqsat2(q,tsen,prsl,ice)
-
- en_bar%values=zero
-
- n_ens_loop: do n=1,n_ens
+ end if
-!$omp parallel do schedule(dynamic,1) private(i,k,j,ic3,hydrometeor,istatus,p3)
+! !$omp parallel do schedule(dynamic,1) private(i,k,j,ic3,hydrometeor,istatus,p3)
do ic3=1,nc3d
hydrometeor = trim(cvars3d(ic3))=='cw' .or. trim(cvars3d(ic3))=='ql' .or. &
@@ -232,14 +216,14 @@ subroutine get_gefs_ensperts_dualres
trim(cvars3d(ic3))=='qs' .or. trim(cvars3d(ic3))=='qg' .or. &
trim(cvars3d(ic3))=='qh'
- call gsi_bundlegetpointer(en_read(n),trim(cvars3d(ic3)),p3,istatus)
- if(istatus/=0) then
- write(6,*)' error retrieving pointer to ',trim(cvars3d(ic3)),' from read in member ',n,m
- call stop2(999)
- end if
if ( hydrometeor ) then
+ call gsi_bundlegetpointer(en_real8(n),trim(cvars3d(ic3)),p3,istatus)
+ if(istatus/=0) then
+ write(6,*)' error retrieving pointer to ',trim(cvars3d(ic3)),' from read in member ',n,m
+ call stop2(999)
+ end if
do k=1,km
do j=1,jm
do i=1,im
@@ -249,13 +233,17 @@ subroutine get_gefs_ensperts_dualres
end do
else if ( trim(cvars3d(ic3)) == 'oz' .and. oz_univ_static ) then
+ call gsi_bundlegetpointer(en_real8(n),trim(cvars3d(ic3)),p3,istatus)
+ if(istatus/=0) then
+ write(6,*)' error retrieving pointer to ',trim(cvars3d(ic3)),' from read in member ',n,m
+ call stop2(999)
+ end if
p3 = zero
end if
end do !c3d
do i=1,nelen
- en_perts(n,1,m)%valuesr4(i)=en_read(n)%values(i)
- en_bar%values(i)=en_bar%values(i)+en_read(n)%values(i)
+ en_bar%values(i)=en_bar%values(i)+en_real8(n)%values(i)*bar_norm
end do
@@ -265,14 +253,13 @@ subroutine get_gefs_ensperts_dualres
! know who would want to commented out code below but be mindful
! of how it interacts with option sst_staticB, please - Todling.
- end do n_ens_loop ! end do over ensemble
-
- do i=1,nelen
- en_bar%values(i)=en_bar%values(i)*bar_norm
- end do
+ end do ! end do over ensembles
+ if (.not.q_hyb_ens) then !use RH
+ deallocate(prsl)
+ end if
+ deallocate(tsen)
! Before converting to perturbations, get ensemble spread
- !-- if (m == 1 .and. write_ens_sprd ) call ens_spread_dualres(en_bar,1)
!!! it is not clear of the next statement is thread/$omp safe.
if (write_ens_sprd ) call ens_spread_dualres(en_bar,m)
@@ -283,7 +270,6 @@ subroutine get_gefs_ensperts_dualres
! Copy pbar to module array. ps_bar may be needed for vertical localization
! in terms of scale heights/normalized p/p
-! Convert to mean
do j=1,jm
do i=1,im
ps_bar(i,j,m)=x2(i,j)
@@ -295,7 +281,7 @@ subroutine get_gefs_ensperts_dualres
!$omp parallel do schedule(dynamic,1) private(n,i,ic3,ipic,k,j)
do n=1,n_ens
do i=1,nelen
- en_perts(n,1,m)%valuesr4(i)=en_perts(n,1,m)%valuesr4(i)-en_bar%values(i)
+ en_perts(n,1,m)%valuesr4(i)=en_real8(n)%values(i)-en_bar%values(i)
end do
if(.not. q_hyb_ens) then
do ic3=1,nc3d
@@ -304,8 +290,8 @@ subroutine get_gefs_ensperts_dualres
do k=1,km
do j=1,jm
do i=1,im
- en_perts(n,1,m)%r3(ipic)%qr4(i,j,k) = min(en_perts(n,1,m)%r3(ipic)%qr4(i,j,k),limqens)
- en_perts(n,1,m)%r3(ipic)%qr4(i,j,k) = max(en_perts(n,1,m)%r3(ipic)%qr4(i,j,k),-limqens)
+ en_perts(n,1,m)%r3(ipic)%qr4(i,j,k) = &
+ max(min(en_perts(n,1,m)%r3(ipic)%qr4(i,j,k),limqens),-limqens)
end do
end do
end do
@@ -316,14 +302,22 @@ subroutine get_gefs_ensperts_dualres
en_perts(n,1,m)%valuesr4(i)=en_perts(n,1,m)%valuesr4(i)*sig_norm
end do
end do
+ if(nsclgrp > 1 .and. global_spectral_filter_sd) then
+ call apply_scaledepwgts(m,grd_ens,sp_ens)
+ end if
end do ntlevs_ens_loop !end do over bins
do n=n_ens,1,-1
- call gsi_bundledestroy(en_read(n),istatus)
+ call gsi_bundledestroy(en_real8(n),istatus)
if ( istatus /= 0 ) &
- call die('get_gefs_ensperts_dualres',': trouble destroying en_read bundle, istatus = ', istatus)
+ call die('get_gefs_ensperts_dualres',': trouble destroying en_real8 bundle, istatus = ', istatus)
end do
- deallocate(en_read)
+ deallocate(en_real8)
+
+ call gsi_bundledestroy(en_bar,istatus)
+
+ if(nsclgrp > 1 .and. global_spectral_filter_sd) call destroy_mult_spc_wgts
+
call gsi_enscoupler_destroy_sub2grid_info(grd_tmp)
! mm1=mype+1
@@ -449,7 +443,7 @@ subroutine ens_spread_dualres(en_bar,ibin)
call stop2(999)
endif
- sp_norm=(one/float(n_ens))
+ sp_norm=(one/real(n_ens,r_kind))
sube%values=zero
do n=1,n_ens
@@ -642,7 +636,7 @@ subroutine write_spread_dualres(ibin,bundle)
return
end subroutine write_spread_dualres
-subroutine general_getprs_glb(ps,tv,prs)
+subroutine general_getprs_glb(ps,tv,prsl)
! subprogram: getprs get 3d pressure or 3d pressure deriv
! prgmmr: kleist org: np20 date: 2005-09-29
!
@@ -674,96 +668,197 @@ subroutine general_getprs_glb(ps,tv,prs)
use kinds,only: r_kind,i_kind
use constants,only: zero,half,one_tenth,rd_over_cp,one
- use gridmod,only: nsig,ak5,bk5,ck5,tref5,idvc5
- use gridmod,only: wrf_nmm_regional,nems_nmmb_regional,eta1_ll,eta2_ll,pdtop_ll,pt_ll,&
- regional,wrf_mass_regional,twodvar_regional,fv3_regional
+ use gridmod,only: nsig,ak5,bk5,ck5,tref5,idvc5,idsl5
use hybrid_ensemble_parameters, only: grd_ens
implicit none
! Declare passed variables
- real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2) ,intent(in ) :: ps
- real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,nsig) ,intent(in ) :: tv
- real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,nsig+1),intent( out) :: prs
+ real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2) ,intent(in ) :: ps
+ real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,nsig),intent(in ) :: tv
+ real(r_kind),dimension(grd_ens%lat2,grd_ens%lon2,nsig),intent( out) :: prsl
! Declare local variables
- real(r_kind) kapr,trk
+ real(r_kind) kapr,trk,kap1
+ real(r_kind),dimension(grd_ens%lat2,nsig+1) :: prs
integer(i_kind) i,j,k,k2 ! ,it
-! Declare local parameter
- real(r_kind),parameter:: ten = 10.0_r_kind
- kapr=one/rd_over_cp
-
- if (regional) then
- if(wrf_nmm_regional.or.nems_nmmb_regional) then
- do k=1,nsig+1
- do j=1,grd_ens%lon2
+ k2=nsig+1
+ kap1=rd_over_cp+one
+ kapr=one/rd_over_cp
+!$omp parallel do schedule(dynamic,1) private(k,j,i,trk,prs)
+ do j=1,grd_ens%lon2
+ do i=1,grd_ens%lat2
+ prs(i,1)=ps(i,j)
+ prs(i,k2)=zero
+ end do
+ if (idvc5 /= 3) then
+ do k=2,nsig
do i=1,grd_ens%lat2
- prs(i,j,k)=one_tenth* &
- (eta1_ll(k)*pdtop_ll + &
- eta2_ll(k)*(ten*ps(i,j)-pdtop_ll-pt_ll) + &
- pt_ll)
+ prs(i,k)=ak5(k)+bk5(k)*ps(i,j)
end do
end do
- end do
- elseif (fv3_regional) then
- do k=1,nsig+1
- do j=1,grd_ens%lon2
+ else
+ do k=1,nsig
do i=1,grd_ens%lat2
- prs(i,j,k)=eta1_ll(k)+ eta2_ll(k)*ps(i,j)
+ trk=(half*(tv(i,j,k-1)+tv(i,j,k))/tref5(k))**kapr
+ prs(i,k)=ak5(k)+(bk5(k)*ps(i,j))+(ck5(k)*trk)
end do
end do
- end do
-
- elseif (twodvar_regional) then
- do k=1,nsig+1
- do j=1,grd_ens%lon2
+ end if
+! Get sensible temperature and 3d layer pressure
+ if (idsl5 /= 2) then
+ do k=1,nsig
do i=1,grd_ens%lat2
- prs(i,j,k)=one_tenth*(eta1_ll(k)*(ten*ps(i,j)-pt_ll) + pt_ll)
+ prsl(i,j,k)=((prs(i,k)**kap1-prs(i,k+1)**kap1)/&
+ (kap1*(prs(i,k)-prs(i,k+1))))**kapr
end do
end do
- end do
- elseif (wrf_mass_regional) then
- do k=1,nsig+1
- do j=1,grd_ens%lon2
+ else
+ do k=1,nsig
do i=1,grd_ens%lat2
- prs(i,j,k)=one_tenth*(eta1_ll(k)*(ten*ps(i,j)-pt_ll) + &
- eta2_ll(k) + pt_ll)
+ prsl(i,j,k)=(prs(i,k)+prs(i,k+1))*half
end do
end do
- end do
- endif
- else
- k=1
- k2=nsig+1
- do j=1,grd_ens%lon2
+ end if
+ end do
+
+ return
+end subroutine general_getprs_glb
+subroutine genqsat2(q,tsen,prsl,ice)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: genqsat
+! prgmmr: derber org: np23 date: 1998-01-14
+!
+! abstract: obtain saturation specific humidity for given temperature.
+!
+! program history log:
+! 1998-01-14 derber
+! 1998-04-05 weiyu yang
+! 1999-08-24 derber, j., treadon, r., yang, w., first frozen mpp version
+! 1903-10-07 Wei Gu, bug fixes,if qs<0,then set qs=0; merge w/ GSI by R Todling
+! 2003-12-23 kleist, use guess pressure, adapt module framework
+! 2004-05-13 kleist, documentation
+! 2004-06-03 treadon, replace ggrid_g3 array with ges_* arrays
+! 2005-02-23 wu, output dlnesdtv
+! 2005-11-21 kleist, derber add dmax array to decouple moisture from temp and
+! pressure for questionable qsat
+! 2006-02-02 treadon - rename prsl as ges_prsl
+! 2006-09-18 derber - modify to limit saturated values near top
+! 2006-11-22 derber - correct bug: es 2._r_kind) .and. &
+ tsen(i,j,k) < mint(i))then
+ lmint(i)=k
+ mint(i)=tsen(i,j,k)
+ end if
end do
end do
- if (idvc5 /= 3) then
-!$omp parallel do schedule(dynamic,1) private(k,j,i)
- do k=2,nsig
- do j=1,grd_ens%lon2
- do i=1,grd_ens%lat2
- prs(i,j,k)=ak5(k)+bk5(k)*ps(i,j)
- end do
- end do
- end do
- else
-!$omp parallel do schedule(dynamic,1) private(k,j,i,trk)
- do k=2,nsig
- do j=1,grd_ens%lon2
- do i=1,grd_ens%lat2
- trk=(half*(tv(i,j,k-1)+tv(i,j,k))/tref5(k))**kapr
- prs(i,j,k)=ak5(k)+(bk5(k)*ps(i,j))+(ck5(k)*trk)
- end do
- end do
- end do
- end if
- end if
+ do i=1,grd_ens%lat2
+ tdry = mint(i)
+ tr = ttp/tdry
+ if (tdry >= ttp .or. .not. ice) then
+ estmax(i) = psat * (tr**xa) * exp(xb*(one-tr))
+ elseif (tdry < tmix) then
+ estmax(i) = psat * (tr**xai) * exp(xbi*(one-tr))
+ else
+ w = (tdry - tmix) / (ttp - tmix)
+ estmax(i) = w * psat * (tr**xa) * exp(xb*(one-tr)) &
+ + (one-w) * psat * (tr**xai) * exp(xbi*(one-tr))
+ endif
+ end do
+ do k = 1,nsig
+ do i = 1,grd_ens%lat2
+ tdry = tsen(i,j,k)
+ tr = ttp/tdry
+ if (tdry >= ttp .or. .not. ice) then
+ es = psat * (tr**xa) * exp(xb*(one-tr))
+ elseif (tdry < tmix) then
+ es = psat * (tr**xai) * exp(xbi*(one-tr))
+ else
+ esw = psat * (tr**xa) * exp(xb*(one-tr))
+ esi = psat * (tr**xai) * exp(xbi*(one-tr))
+ w = (tdry - tmix) / (ttp - tmix)
+ es = w * esw + (one-w) * esi
+! es = w * psat * (tr**xa) * exp(xb*(one-tr)) &
+! + (one-w) * psat * (tr**xai) * exp(xbi*(one-tr))
+
+ endif
+
+ pw = onep3*prsl(i,j,k)
+ if(lmint(i) < k)then
+ esmax=0.1_r_kind*pw
+ esmax=min(esmax,estmax(i))
+ es=min(es,esmax)
+ end if
+ qs = max(qmin, eps * es / (pw - omeps * es))
+ q(i,j,k) = q(i,j,k)/qs
+
+ end do
+ end do
+ end do
return
-end subroutine general_getprs_glb
+end subroutine genqsat2
+
diff --git a/src/gsi/get_gefs_for_regional.f90 b/src/gsi/get_gefs_for_regional.f90
index a076f0ccfd..cc5e0a2c86 100644
--- a/src/gsi/get_gefs_for_regional.f90
+++ b/src/gsi/get_gefs_for_regional.f90
@@ -41,7 +41,7 @@ subroutine get_gefs_for_regional
fv3_regional
use hybrid_ensemble_parameters, only: region_lat_ens,region_lon_ens
use hybrid_ensemble_parameters, only: en_perts,ps_bar,nelen
- use hybrid_ensemble_parameters, only: n_ens_gfs,grd_ens,grd_a1,grd_e1,p_e2a,uv_hyb_ens,dual_res
+ use hybrid_ensemble_parameters, only: n_ens_gfs,weight_ens_gfs,grd_ens,grd_a1,grd_e1,p_e2a,uv_hyb_ens,dual_res
use hybrid_ensemble_parameters, only: full_ensemble,q_hyb_ens,l_ens_in_diff_time,write_ens_sprd
use hybrid_ensemble_parameters, only: ntlevs_ens,ensemble_path,jcap_ens
use control_vectors, only: cvars2d,cvars3d,nc2d,nc3d
@@ -304,8 +304,8 @@ subroutine get_gefs_for_regional
if (nframe /= 0) call error_msg(trim(my_name),trim(filename),'nframe', &
'getfilehead',istop,nframe)
- fhour = float(nfhour) + float(nfminute)/r60 + &
- float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
nlat_gfs=latb+2
nlon_gfs=lonb
@@ -897,8 +897,8 @@ subroutine get_gefs_for_regional
iimin=min(ii,iimin)
jjmax=max(jj,jjmax)
jjmin=min(jj,jjmin)
- dlon_ens=float(jj)
- dlat_ens=float(ii)
+ dlon_ens=real(jj,r_kind)
+ dlat_ens=real(ii,r_kind)
dlon=one+(dlon_ens-one)*ratio_x
dlat=one+(dlat_ens-one)*ratio_y
call rotate_wind_ll2xy(work_sub(1,i,j,ku),work_sub(1,i,j,kv), &
@@ -992,7 +992,7 @@ subroutine get_gefs_for_regional
end do
! Convert to mean
- bar_norm = one/float(n_ens_gfs)
+ bar_norm = one/real(n_ens_gfs,r_kind)
do k=1,grd_mix%nsig
do j=1,grd_mix%lon2
do i=1,grd_mix%lat2
@@ -1311,7 +1311,7 @@ subroutine get_gefs_for_regional
! 2*J_b = x^T * (beta1*B + beta2*P_ens)^(-1) * x
! where P_ens is the ensemble covariance which is the sum of outer products of the
! ensemble perturbations (unnormalized) divided by n_ens-1 (or n_ens, depending on who you read).
- sig_norm=sqrt(one/max(one,n_ens_temp-one))
+ sig_norm=sqrt(weight_ens_gfs/max(one,n_ens_temp-one))
! if(n_ens_temp==n_ens.and.n==n_ens+1) sig_norm=one
! if(n==1 .or. n==2 .or. n==50) then
diff --git a/src/gsi/get_nmmb_ensperts.f90 b/src/gsi/get_nmmb_ensperts.f90
index ece1780c03..4dc3254ccd 100644
--- a/src/gsi/get_nmmb_ensperts.f90
+++ b/src/gsi/get_nmmb_ensperts.f90
@@ -313,7 +313,7 @@ subroutine get_nmmb_ensperts
end do ! end do over ensemble
! Convert to mean
- bar_norm = one/float(n_ens)
+ bar_norm = one/real(n_ens,r_kind)
en_bar%values=en_bar%values*bar_norm
! Copy pbar to module array. ps_bar may be needed for vertical localization
diff --git a/src/gsi/getsiga.f90 b/src/gsi/getsiga.f90
index 788e0652d7..ad47017be1 100644
--- a/src/gsi/getsiga.f90
+++ b/src/gsi/getsiga.f90
@@ -198,6 +198,7 @@ subroutine view_cv_ad (xhat,mydate,filename,readcv)
use state_vectors, only: allocate_state,deallocate_state,prt_state_norms
use bias_predictors, only: predictors,allocate_preds,deallocate_preds,assignment(=)
use bias_predictors, only: read_preds
+use control2state_mod, only: control2state_ad
implicit none
type(control_vector) :: xhat
integer(i_kind), intent(in) :: mydate(5) ! as in iadate or ibdate, or similar
diff --git a/src/gsi/gfs_stratosphere.f90 b/src/gsi/gfs_stratosphere.f90
index 22581b2db0..6014045c76 100644
--- a/src/gsi/gfs_stratosphere.f90
+++ b/src/gsi/gfs_stratosphere.f90
@@ -308,8 +308,8 @@ subroutine mix_gfs_nmmb_vcoords(deta1 ,aeta1 ,eta1 ,deta2 ,aeta2 ,eta2 ,pdtop,pt
if (nframe /= 0) call error_msg(trim(my_name),trim(filename),'nframe', &
'getfilehead',istop,nframe)
- fhour = float(nfhour) + float(nfminute)/r60 + &
- float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
write(6,*) ' input filename=',filename
write(6,*) ' nemsio head: fhour,idate=',fhour,idate
write(6,*) ' nemsio head: levs=',levs
@@ -1183,8 +1183,8 @@ subroutine add_gfs_stratosphere
if ( nframe /= 0 ) call error_msg(trim(my_name),trim(filename),'nframe', &
'getfilehead',istop,nframe)
- fhour = float(nfhour) + float(nfminute)/r60 + &
- float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
if ( mype == 0 ) then
write(6,*) ' input filename=',filename
write(6,*) ' nemsio head: fhour,idate=',fhour,idate
@@ -1545,8 +1545,8 @@ subroutine add_gfs_stratosphere
jj=j+grd_mix%jstart(mm1)-2
ii=min(grd_mix%nlat,max(1,ii))
jj=min(grd_mix%nlon,max(1,jj))
- dlon=float(jj)
- dlat=float(ii)
+ dlon=real(jj,r_kind)
+ dlat=real(ii,r_kind)
do k=1,nsig_save
xspli_r(k)=log(prsl_r(i,j,k)*ten)
enddo
diff --git a/src/gsi/grdcrd.f90 b/src/gsi/grdcrd.f90
index c20e02ce7f..bb655fc68b 100644
--- a/src/gsi/grdcrd.f90
+++ b/src/gsi/grdcrd.f90
@@ -63,7 +63,7 @@ subroutine grdcrd(d,nd,x,nx,flg)
ix=isrchf(nx-1,x,d(id),flg)-1
end if
end if
- d(id)=float(ix)+(d(id)-x(ix))/(x(ix+1)-x(ix))
+ d(id)=real(ix,r_kind)+(d(id)-x(ix))/(x(ix+1)-x(ix))
end do
! Treat special case of nx=1
@@ -135,7 +135,7 @@ subroutine grdcrd1(d,x,nx,flg)
ix=isrchf(nx-1,x,d,flg)-1
end if
end if
- d=float(ix)+(d-x(ix))/(x(ix+1)-x(ix))
+ d=real(ix,r_kind)+(d-x(ix))/(x(ix+1)-x(ix))
! Treat special case of nx=1
elseif (nx==1) then
diff --git a/src/gsi/gridmod.F90 b/src/gsi/gridmod.F90
index 928b9e9c43..2367899ea5 100644
--- a/src/gsi/gridmod.F90
+++ b/src/gsi/gridmod.F90
@@ -93,6 +93,7 @@ module gridmod
! 2019-09-23 martin - add use_gfs_ncio to read global first guess from netCDF file
! 2020-12-18 Hu - add grid_type_fv3_regional
! 2021-12-30 Hu - add fv3_io_layout_y
+! 2022-03-01 X.Lu & X.Wang - add corresponding variables for dual ens for HAFS. POC: xuguang.wang@ou.edu
!
!
!
@@ -130,6 +131,7 @@ module gridmod
public :: vectosub
public :: reload
public :: strip_periodic
+ public :: minmype
! set passed variables to public
public :: nnnn1o,iglobal,itotsub,ijn,ijn_s,lat2,lon2,lat1,lon1,nsig,nsig_soil
@@ -145,6 +147,7 @@ module gridmod
public :: regional_fhr,region_dyi,coeffx,region_dxi,coeffy,nsig_hlf,regional_fmin
public :: nsig2,wgtlats,corlats,rbs2,ncepgfs_headv,regional_time,wgtfactlats
public :: nlat_regional,nlon_regional,update_regsfc,half_grid,gencode
+ public :: nlat_regionalens,nlon_regionalens
public :: diagnostic_reg,nmmb_reference_grid,filled_grid
public :: grid_ratio_nmmb,isd_g,isc_g,dx_gfs,lpl_gfs,nsig5,nmmb_verttype
public :: grid_ratio_fv3_regional,fv3_io_layout_y,fv3_regional,fv3_cmaq_regional,grid_type_fv3_regional
@@ -267,6 +270,7 @@ module gridmod
integer(i_kind) jcap ! spectral triangular truncation of ncep global analysis
integer(i_kind) jcap_b ! spectral triangular truncation of ncep global background
integer(i_kind) nthreads ! number of threads used (currently only used in calctends routines)
+ integer(i_kind) minmype ! processor with minimum size subdomain
logical periodic ! logical flag for periodic e/w domains
@@ -327,7 +331,7 @@ module gridmod
real(r_kind) rlon_min_dd,rlon_max_dd,rlat_min_dd,rlat_max_dd
real(r_kind) dt_ll,pdtop_ll,pt_ll
- integer(i_kind) nlon_regional,nlat_regional
+ integer(i_kind) nlon_regional,nlat_regional,nlon_regionalens,nlat_regionalens
real(r_kind) regional_fhr,regional_fmin
integer(i_kind) regional_time(6)
integer(i_kind) jcap_gfs,nlat_gfs,nlon_gfs
@@ -483,6 +487,8 @@ subroutine init_grid
update_regsfc = .false.
nlon_regional = 0
nlat_regional = 0
+ nlon_regionalens = 0
+ nlat_regionalens = 0
msig = nsig
do k=1,size(nlayers)
@@ -574,7 +580,7 @@ subroutine init_grid_vars(jcap,npe,cvars3d,cvars2d,cvars,mype)
integer(i_kind) n3d,n2d,nvars,tid,nth
integer(i_kind) ipsf,ipvp,jpsf,jpvp,isfb,isfe,ivpb,ivpe
integer(i_kind) istatus,icw,iql,iqi
- integer(i_kind) icw_cv,iql_cv,iqi_cv
+ integer(i_kind) icw_cv,iql_cv,iqi_cv,minmax
logical,allocatable,dimension(:):: vector
logical print_verbose
@@ -687,6 +693,8 @@ subroutine init_grid_vars(jcap,npe,cvars3d,cvars2d,cvars,mype)
periodic=grd_a%periodic
+ minmype=0
+ minmax=grd_a%ilat1(1)*grd_a%jlon1(1)
do i=1,npe
istart(i) =grd_a%istart(i)
jstart(i) =grd_a%jstart(i)
@@ -699,7 +707,12 @@ subroutine init_grid_vars(jcap,npe,cvars3d,cvars2d,cvars,mype)
displs_s(i) =grd_a%displs_s(i)
ijn(i) =grd_a%ijn(i)
displs_g(i) =grd_a%displs_g(i)
+ if(grd_a%ilat1(i)*grd_a%jlon1(i)< minmax)then
+ minmax=grd_a%ilat1(i)*grd_a%jlon1(i)
+ minmype=i-1
+ end if
end do
+ if(mype == minmype) write(6,*) ' minmype = ',minmype
!#omp parallel private(nth,tid)
nth = omp_get_max_threads()
diff --git a/src/gsi/gsd_update_mod.f90 b/src/gsi/gsd_update_mod.f90
index 7b43f55fb2..35f7663322 100644
--- a/src/gsi/gsd_update_mod.f90
+++ b/src/gsi/gsd_update_mod.f90
@@ -699,7 +699,7 @@ subroutine gsd_gen_coast_prox
nip = nip+1
end do
end do
- hcoast_prox(1,i,j) = float(nco)/float (nip)
+ hcoast_prox(1,i,j) = real(nco,r_kind)/real(nip,r_kind)
end if
end do
end do
diff --git a/src/gsi/gsdcloudanalysis.F90 b/src/gsi/gsdcloudanalysis.F90
index 21fc21b8a2..6df710cf32 100644
--- a/src/gsi/gsdcloudanalysis.F90
+++ b/src/gsi/gsdcloudanalysis.F90
@@ -65,7 +65,7 @@ subroutine gsdcloudanalysis(mype)
!
!
use constants, only: zero,one,rad2deg,fv
- use constants, only: rd_over_cp, h1000
+ use constants, only: rd_over_cp,h1000
use kinds, only: r_single,i_kind, r_kind
use gridmod, only: pt_ll,eta1_ll,aeta1_ll,eta2_ll,aeta2_ll
use gridmod, only: regional,wrf_mass_regional,regional_time
diff --git a/src/gsi/gsdcloudlib_pseudoq_mod.f90 b/src/gsi/gsdcloudlib_pseudoq_mod.f90
index b7544a860c..3b04558da7 100644
--- a/src/gsi/gsdcloudlib_pseudoq_mod.f90
+++ b/src/gsi/gsdcloudlib_pseudoq_mod.f90
@@ -192,9 +192,9 @@ SUBROUTINE cloudCover_Surface_col(mype,nsig, &
endif
! convert cloud base observation from AGL to ASL
- cl_base_ista = float(ocld(6+ic)) + Oelvtn - zh
+ cl_base_ista = real(ocld(6+ic),r_kind) + Oelvtn - zh
if(zh < 1.0_r_kind .and. Oelvtn > 20.0_r_kind &
- .and. float(ocld(6+ic)) < 250.0_r_kind) then
+ .and. real(ocld(6+ic),r_kind) < 250.0_r_kind) then
cycle ! limit the use of METAR station over oceas for low cloud base
endif
@@ -267,7 +267,7 @@ SUBROUTINE cloudCover_Surface_col(mype,nsig, &
! -- Use visibility for low-level cloud whether
if (wthr_type < 30 .and. wthr_type > 20 .and. &
ocld(13) < 5000 .and. ocld(13) > 1 ) then
- betav = 3.912_r_kind / (float(ocld(13)) / 1000._r_kind)
+ betav = 3.912_r_kind / (real(ocld(13),r_kind) / 1000._r_kind)
vis2qc = ( (betav/144.7_r_kind) ** 1.14_r_kind) / 1000._r_kind
endif ! cloud or clear
diff --git a/src/gsi/gsi_dbzOper.F90 b/src/gsi/gsi_dbzOper.F90
index 74d9bdf65d..4a63d0995f 100644
--- a/src/gsi/gsi_dbzOper.F90
+++ b/src/gsi/gsi_dbzOper.F90
@@ -83,6 +83,10 @@ subroutine setup_(self, lunin, mype, is, nobs, init_pass,last_pass)
use jfunc , only: jiter
use mpeu_util, only: die
+
+ use directDA_radaruse_mod, only: l_use_dbz_directDA
+ use obsmod, only: dirname, ianldate
+
implicit none
class(dbzOper ), intent(inout):: self
integer(i_kind), intent(in):: lunin
@@ -99,8 +103,25 @@ subroutine setup_(self, lunin, mype, is, nobs, init_pass,last_pass)
character(len=len_isis ):: isis
integer(i_kind):: nreal,nchanl,ier,nele
logical:: diagsave
+ integer(i_kind):: lu_diag
+ character(128):: diag_file
+ character(80):: string
+
+ if(nobs == 0) then
- if(nobs == 0) return
+ if( (mype == 0) .and. init_pass .and. (.not. l_use_dbz_directDA) ) then
+ write(string,600) jiter
+600 format('radardbz_',i2.2)
+ diag_file=trim(dirname) // trim(string)
+ write(6,*) 'write ianldate to ', diag_file
+ open(newunit=lu_diag,file=trim(diag_file),form='unformatted',status='unknown',position='rewind')
+ write(lu_diag) ianldate
+ close(lu_diag)
+ endif
+
+ return
+
+ endif
read(lunin,iostat=ier) obstype,isis,nreal,nchanl
if(ier/=0) call die(myname_,'read(obstype,...), iostat =',ier)
diff --git a/src/gsi/gsi_fedOper.F90 b/src/gsi/gsi_fedOper.F90
new file mode 100644
index 0000000000..e704a1c056
--- /dev/null
+++ b/src/gsi/gsi_fedOper.F90
@@ -0,0 +1,184 @@
+module gsi_fedOper
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: module gsi_fedOper
+!
+! abstract: an obOper extension for fedNode type
+!
+! program history log:
+! 2023-07-10 D. Dowell - created new module for FED (flash extent
+! density); gsi_dbzOper.F90 code used as a
+! starting point for developing this new module
+! 2023-08-24 H. Wang - Turned on intfed and stpfed
+!
+! input argument list: see Fortran 90 style document below
+!
+! output argument list: see Fortran 90 style document below
+!
+! attributes:
+! language: Fortran 90 and/or above
+! machine:
+!
+!$$$ end subprogram documentation block
+
+! module interface:
+
+ use gsi_obOper, only: obOper
+ use m_fedNode , only: fedNode
+ implicit none
+ public:: fedOper ! data structure
+ public:: diag_fed
+
+ type,extends(obOper):: fedOper
+ contains
+ procedure,nopass:: mytype
+ procedure,nopass:: nodeMold
+ procedure:: setup_
+ procedure:: intjo1_
+ procedure:: stpjo1_
+ end type fedOper
+
+! def diag_fed- namelist logical to compute/write (=true) FED diag files
+ logical,save:: diag_fed=.false.
+
+!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ character(len=*),parameter :: myname='gsi_fedOper'
+ type(fedNode),save,target:: myNodeMold_
+
+contains
+ function mytype(nodetype)
+ implicit none
+ character(len=:),allocatable:: mytype
+ logical,optional, intent(in):: nodetype
+ mytype="[fedOper]"
+ if(present(nodetype)) then
+ if(nodetype) mytype=myNodeMold_%mytype()
+ endif
+ end function mytype
+
+ function nodeMold()
+ !> %nodeMold() returns a mold of its corresponding obsNode
+ use m_obsNode, only: obsNode
+ implicit none
+ class(obsNode),pointer:: nodeMold
+ nodeMold => myNodeMold_
+ end function nodeMold
+
+ subroutine setup_(self, lunin, mype, is, nobs, init_pass, last_pass)
+ use fed_setup, only: setup
+ use kinds, only: i_kind
+ use gsi_obOper, only: len_obstype
+ use gsi_obOper, only: len_isis
+
+ use m_rhs , only: awork => rhs_awork
+ use m_rhs , only: bwork => rhs_bwork
+ use m_rhs , only: iwork => i_fed
+
+ use obsmod , only: write_diag
+ use jfunc , only: jiter
+
+ use mpeu_util, only: die
+
+ use obsmod, only: dirname, ianldate
+
+ implicit none
+ class(fedOper ), intent(inout):: self
+ integer(i_kind), intent(in):: lunin
+ integer(i_kind), intent(in):: mype
+ integer(i_kind), intent(in):: is
+ integer(i_kind), intent(in):: nobs
+ logical , intent(in):: init_pass ! supporting multi-pass setup()
+ logical , intent(in):: last_pass ! with incremental backgrounds.
+
+ !----------------------------------------
+ character(len=*),parameter:: myname_=myname//"::setup_"
+
+ character(len=len_obstype):: obstype
+ character(len=len_isis ):: isis
+ integer(i_kind):: nreal,nchanl,ier,nele
+ logical:: diagsave
+ integer(i_kind):: lu_diag
+ character(128):: diag_file
+ character(80):: string
+
+ if(nobs == 0) then
+
+ if( (mype == 0) .and. init_pass ) then
+ write(string,600) jiter
+600 format('fed_',i2.2)
+ diag_file=trim(dirname) // trim(string)
+ write(6,*) 'write ianldate to ', diag_file
+ open(newunit=lu_diag,file=trim(diag_file),form='unformatted',status='unknown',position='rewind')
+ write(lu_diag) ianldate
+ close(lu_diag)
+ endif
+
+ return
+
+ endif
+
+ read(lunin,iostat=ier) obstype,isis,nreal,nchanl
+ if(ier/=0) call die(myname_,'read(obstype,...), iostat =',ier)
+ nele = nreal+nchanl
+
+ diagsave = write_diag(jiter) .and. diag_fed
+
+ call setup(self%obsLL(:), self%odiagLL(:), &
+ lunin,mype,bwork,awork(:,iwork),nele,nobs,is,diagsave,init_pass)
+
+ end subroutine setup_
+
+ subroutine intjo1_(self, ibin, rval,sval, qpred,sbias)
+ use intfedmod, only: intjo => intfed
+ use gsi_bundlemod , only: gsi_bundle
+ use bias_predictors, only: predictors
+ use m_obsNode , only: obsNode
+ use m_obsLList, only: obsLList_headNode
+ use kinds , only: i_kind, r_quad
+ implicit none
+ class(fedOper ),intent(in ):: self
+ integer(i_kind ),intent(in ):: ibin
+ type(gsi_bundle),intent(inout):: rval ! (ibin)
+ type(gsi_bundle),intent(in ):: sval ! (ibin)
+ real(r_quad ),target,dimension(:),intent(inout):: qpred ! (ibin)
+ type(predictors),target, intent(in ):: sbias
+
+ !----------------------------------------
+ character(len=*),parameter:: myname_=myname//"::intjo1_"
+ class(obsNode),pointer:: headNode
+
+ headNode => obsLList_headNode(self%obsLL(ibin))
+ call intjo(headNode, rval,sval)
+ headNode => null()
+
+ end subroutine intjo1_
+
+ subroutine stpjo1_(self, ibin, dval,xval,pbcjo,sges,nstep,dbias,xbias)
+ use stpfedmod, only: stpjo => stpfed
+ use gsi_bundlemod, only: gsi_bundle
+ use bias_predictors, only: predictors
+ use m_obsNode , only: obsNode
+ use m_obsLList, only: obsLList_headNode
+ use kinds, only: r_quad,r_kind,i_kind
+ implicit none
+ class(fedOper ),intent(in):: self
+ integer(i_kind ),intent(in):: ibin
+ type(gsi_bundle),intent(in):: dval
+ type(gsi_bundle),intent(in):: xval
+ real(r_quad ),dimension(:),intent(inout):: pbcjo ! (1:4)
+ real(r_kind ),dimension(:),intent(in ):: sges
+ integer(i_kind),intent(in):: nstep
+
+ type(predictors),target, intent(in):: dbias
+ type(predictors),target, intent(in):: xbias
+
+ !----------------------------------------
+ character(len=*),parameter:: myname_=myname//"::stpjo1_"
+ class(obsNode),pointer:: headNode
+
+ headNode => obsLList_headNode(self%obsLL(ibin))
+ call stpjo(headNode,dval,xval,pbcjo(:),sges,nstep)
+ headNode => null()
+ end subroutine stpjo1_
+
+end module gsi_fedOper
diff --git a/src/gsi/gsi_files.cmake b/src/gsi/gsi_files.cmake
index 461b49ddf6..95d885e2ee 100644
--- a/src/gsi/gsi_files.cmake
+++ b/src/gsi/gsi_files.cmake
@@ -87,6 +87,7 @@ anisofilter_glb.f90
antcorr_application.f90
antest_maps0.f90
antest_maps0_glb.f90
+apply_scaledepwgts.f90
atms_spatial_average_mod.f90
balmod.f90
berror.f90
@@ -100,6 +101,7 @@ bkgvar_rewgt.f90
blacklist.f90
blendmod.f90
buddycheck_mod.f90
+cads.f90
calc_fov_conical.f90
calc_fov_crosstrk.f90
calctends.f90
@@ -123,7 +125,6 @@ constants.f90
control2model.f90
control2model_ad.f90
control2state.f90
-control2state_ad.f90
control_vectors.f90
convb_ps.f90
convb_q.f90
@@ -156,7 +157,6 @@ ens_spread_mod.f90
ensctl2model.f90
ensctl2model_ad.f90
ensctl2state.f90
-ensctl2state_ad.f90
evaljgrad.f90
evaljo.f90
evalqlim.f90
@@ -217,6 +217,7 @@ gsi_colvkOper.F90
gsi_dbzOper.F90
gsi_dwOper.F90
gsi_enscouplermod.f90
+gsi_fedOper.F90
gsi_gpsbendOper.F90
gsi_gpsrefOper.F90
gsi_gustOper.F90
@@ -273,6 +274,7 @@ intaod.f90
intcldch.f90
intco.f90
intdbz.f90
+intfed.f90
intdw.f90
intgps.f90
intgust.f90
@@ -338,6 +340,7 @@ m_distance.f90
m_dtime.F90
m_dwNode.F90
m_extOzone.F90
+m_fedNode.F90
m_find.f90
m_gpsNode.F90
m_gpsrhs.F90
@@ -478,6 +481,7 @@ read_cris.f90
read_dbz_nc.f90
read_dbz_netcdf.f90
read_diag.f90
+read_fed.f90
read_files.f90
read_fl_hdob.f90
read_gfs_ozone_for_regional.f90
@@ -532,6 +536,7 @@ setupco.f90
setupdbz.f90
setupdbz_lib.f90
setupdw.f90
+setupfed.f90
setupgust.f90
setuphowv.f90
setuplag.f90
@@ -590,6 +595,7 @@ stpcalc.f90
stpcldch.f90
stpco.f90
stpdbz.f90
+stpfed.f90
stpdw.f90
stpgps.f90
stpgust.f90
diff --git a/src/gsi/gsi_obOperTypeManager.F90 b/src/gsi/gsi_obOperTypeManager.F90
index ea306953c4..6db7921905 100644
--- a/src/gsi/gsi_obOperTypeManager.F90
+++ b/src/gsi/gsi_obOperTypeManager.F90
@@ -66,6 +66,7 @@ module gsi_obOperTypeManager
use gsi_lightOper , only: lightOper
use gsi_dbzOper , only: dbzOper
+ use gsi_fedOper , only: fedOper
use gsi_cldtotOper , only: cldtotOper
use kinds , only: i_kind
@@ -136,6 +137,7 @@ module gsi_obOperTypeManager
public:: iobOper_lwcp
public:: iobOper_light
public:: iobOper_dbz
+ public:: iobOper_fed
public:: iobOper_cldtot
enum, bind(C)
@@ -181,6 +183,7 @@ module gsi_obOperTypeManager
enumerator:: iobOper_lwcp
enumerator:: iobOper_light
enumerator:: iobOper_dbz
+ enumerator:: iobOper_fed
enumerator:: iobOper_cldtot
enumerator:: iobOper_extra_
@@ -242,6 +245,7 @@ module gsi_obOperTypeManager
type( lwcpOper), target, save:: lwcpOper_mold
type( lightOper), target, save:: lightOper_mold
type( dbzOper), target, save:: dbzOper_mold
+ type( fedOper), target, save:: fedOper_mold
type( cldtotOper), target, save:: cldtotOper_mold
contains
@@ -276,6 +280,9 @@ function dtype2index_(dtype) result(index_)
case("ompstc8"); index_= iobOper_oz
case("ompsnp" ); index_= iobOper_oz
case("ompsnm" ); index_= iobOper_oz
+ case("omieff" ); index_= iobOper_oz
+ case("tomseff" ); index_= iobOper_oz
+ case("ompsnmeff"); index_= iobOper_oz
case("o3l" ,"[o3loper]" ); index_= iobOper_o3l
case("o3lev" ); index_= iobOper_o3l
@@ -283,11 +290,10 @@ function dtype2index_(dtype) result(index_)
case("mls22" ); index_= iobOper_o3l
case("mls30" ); index_= iobOper_o3l
case("mls55" ); index_= iobOper_o3l
- case("omieff" ); index_= iobOper_o3l
- case("tomseff" ); index_= iobOper_o3l
+ case("ompslp" ); index_= iobOper_o3l
case("ompslpuv" ); index_= iobOper_o3l
case("ompslpvis"); index_= iobOper_o3l
- case("ompslp" ); index_= iobOper_o3l
+ case("ompslpnc" ); index_= iobOper_o3l
case("gpsbend","[gpsbendoper]"); index_= iobOper_gpsbend
case("gps_bnd"); index_= iobOper_gpsbend
@@ -388,6 +394,7 @@ function dtype2index_(dtype) result(index_)
case("goes_glm" ); index_= iobOper_light
case("dbz" ,"[dbzoper]" ); index_= iobOper_dbz
+ case("fed" ,"[fedoper]" ); index_= iobOper_fed
case("cldtot" ,"[cldtotoper]" ); index_= iobOper_cldtot
case("mta_cld" ); index_= iobOper_cldtot
@@ -485,6 +492,7 @@ function index2vmold_(iobOper) result(vmold_)
case(iobOper_lwcp ); vmold_ => lwcpOper_mold
case(iobOper_light ); vmold_ => lightOper_mold
case(iobOper_dbz ); vmold_ => dbzOper_mold
+ case(iobOper_fed ); vmold_ => fedOper_mold
case(iobOper_cldtot ); vmold_ => cldtotOper_mold
case( obOper_undef ); vmold_ => null()
@@ -600,6 +608,7 @@ subroutine cobstype_config_()
cobstype(iobOper_lwcp ) ="lwcp " ! lwcp_ob_type
cobstype(iobOper_light ) ="light " ! light_ob_type
cobstype(iobOper_dbz ) ="dbz " ! dbz_ob_type
+ cobstype(iobOper_fed ) ="fed " ! fed_ob_type
cobstype(iobOper_cldtot ) ="cldtot " ! using q_ob_type
cobstype_configured_=.true.
diff --git a/src/gsi/gsi_rfv3io_mod.f90 b/src/gsi/gsi_rfv3io_mod.f90
index eb7a86160f..8e1c3ab98f 100644
--- a/src/gsi/gsi_rfv3io_mod.f90
+++ b/src/gsi/gsi_rfv3io_mod.f90
@@ -18,13 +18,18 @@ module gsi_rfv3io_mod
! This function is needed when fv3 model sets
! io_layout(2)>1
! 2022-02-15 Lu @ Wang - add time label it for FGAT. POC: xuguang.wang@ou.edu
+! 2022-03-01 X.Lu @ X.Wang - add gsi_rfv3io_get_ens_grid_specs for dual ens HAFS. POC: xuguang.wang@ou.edu
! 2022-03-15 Hu - add code to read/write 2m T and Q for they will be
! used as background for surface observation operator
! 2022-04-15 Wang - add IO for regional FV3-CMAQ (RRFS-CMAQ) model
! 2022-08-10 Wang - add IO for regional FV3-SMOKE (RRFS-SMOKE) model
+! 2023-07-30 Zhao - add IO for the analysis of the significant wave height
+! (SWH, aka howv in GSI) in fv3-lam based DA (eg., RRFS-3DRTMA)
+! 2024-01-24 X.Zhang - bug fix for reading the soil temp and mois from the wram start file
!
! subroutines included:
! sub gsi_rfv3io_get_grid_specs
+! sub gsi_rfv3io_get_ens_grid_specs
! sub read_fv3_files
! sub read_fv3_netcdf_guess
! sub gsi_fv3ncdf2d_read
@@ -47,8 +52,8 @@ module gsi_rfv3io_mod
!$$$ end documentation block
use kinds, only: r_kind,i_kind
- use gridmod, only: nlon_regional,nlat_regional
- use constants, only:max_varname_length
+ use gridmod, only: nlon_regional,nlat_regional,nlon_regionalens,nlat_regionalens
+ use constants, only:max_varname_length,max_filename_length
use gsi_bundlemod, only : gsi_bundle
use general_sub2grid_mod, only: sub2grid_info
use gridmod, only: fv3_io_layout_y
@@ -56,6 +61,7 @@ module gsi_rfv3io_mod
use rapidrefresh_cldsurf_mod, only: i_use_2mq4b,i_use_2mt4b
use chemmod, only: naero_cmaq_fv3,aeronames_cmaq_fv3,imodes_cmaq_fv3,laeroana_fv3cmaq
use chemmod, only: naero_smoke_fv3,aeronames_smoke_fv3,laeroana_fv3smoke
+ use rapidrefresh_cldsurf_mod, only: i_howv_3dda, i_gust_3dda
implicit none
public type_fv3regfilenameg
@@ -68,6 +74,7 @@ module gsi_rfv3io_mod
character(len=:),allocatable :: ak_bk !='fv3_akbk'
character(len=:),allocatable :: dynvars !='fv3_dynvars'
character(len=:),allocatable :: tracers !='fv3_tracer'
+ character(len=:),allocatable :: phyvars !='fv3_phyvars'
character(len=:),allocatable :: sfcdata !='fv3_sfcdata'
character(len=:),allocatable :: couplerres!='coupler.res'
contains
@@ -78,7 +85,9 @@ module gsi_rfv3io_mod
type(type_fv3regfilenameg),allocatable:: bg_fv3regfilenameg(:)
integer(i_kind) nx,ny,nz
+ integer(i_kind) nxens,nyens
integer(i_kind),dimension(:),allocatable :: ny_layout_len,ny_layout_b,ny_layout_e
+ integer(i_kind),dimension(:),allocatable :: ny_layout_lenens,ny_layout_bens,ny_layout_eens
real(r_kind),allocatable:: grid_lon(:,:),grid_lont(:,:),grid_lat(:,:),grid_latt(:,:)
real(r_kind),allocatable:: ak(:),bk(:)
integer(i_kind),allocatable:: ijns2d(:),displss2d(:),ijns(:),displss(:)
@@ -91,8 +100,9 @@ module gsi_rfv3io_mod
type(sub2grid_info) :: grd_fv3lam_tracer_ionouv
type(sub2grid_info) :: grd_fv3lam_tracerchem_ionouv
type(sub2grid_info) :: grd_fv3lam_tracersmoke_ionouv
+ type(sub2grid_info) :: grd_fv3lam_phyvar_ionouv
type(sub2grid_info) :: grd_fv3lam_uv
- integer(i_kind) ,parameter:: ndynvarslist=13, ntracerslist=8
+ integer(i_kind) ,parameter:: ndynvarslist=13, ntracerslist=8, nphyvarslist=2
character(len=max_varname_length), dimension(ndynvarslist), parameter :: &
vardynvars = [character(len=max_varname_length) :: &
@@ -100,13 +110,20 @@ module gsi_rfv3io_mod
character(len=max_varname_length), dimension(ntracerslist+naero_cmaq_fv3+7+naero_smoke_fv3), parameter :: &
vartracers = [character(len=max_varname_length) :: &
'q','oz','ql','qi','qr','qs','qg','qnr',aeronames_cmaq_fv3,'pm25at','pm25ac','pm25co','pm2_5','amassi','amassj','amassk',aeronames_smoke_fv3]
- character(len=max_varname_length), dimension(15+naero_cmaq_fv3+7+naero_smoke_fv3), parameter :: &
+ character(len=max_varname_length), dimension(nphyvarslist), parameter :: &
+ varphyvars = [character(len=max_varname_length) :: 'dbz','fed']
+ character(len=max_varname_length), dimension(16+naero_cmaq_fv3+7+naero_smoke_fv3+1), parameter :: &
varfv3name = [character(len=max_varname_length) :: &
- 'u','v','W','T','delp','sphum','o3mr','liq_wat','ice_wat','rainwat','snowwat','graupel','rain_nc','ps','DZ', &
+ 'u','v','W','T','delp','sphum','o3mr','liq_wat','ice_wat','rainwat','snowwat','graupel','rain_nc','ref_f3d','flash_extent_density','ps','DZ', &
aeronames_cmaq_fv3,'pm25at','pm25ac','pm25co','pm2_5','amassi','amassj','amassk',aeronames_smoke_fv3], &
vgsiname = [character(len=max_varname_length) :: &
- 'u','v','w','tsen','delp','q','oz','ql','qi','qr','qs','qg','qnr','ps','delzinc', &
+ 'u','v','w','tsen','delp','q','oz','ql','qi','qr','qs','qg','qnr','dbz','fed','ps','delzinc', &
aeronames_cmaq_fv3,'pm25at','pm25ac','pm25co','pm2_5','amassi','amassj','amassk',aeronames_smoke_fv3]
+
+ integer(i_kind) ,parameter:: nnonnegtracer=7
+ character(len=max_varname_length), dimension(nnonnegtracer), parameter :: &
+ vnames_nonnegativetracers = [character(len=max_varname_length) :: &
+ "sphum","o3mr","liq_wat","ice_wat","rainwat","snowwat","graupel"]
character(len=max_varname_length),dimension(:),allocatable:: name_metvars2d
character(len=max_varname_length),dimension(:),allocatable:: name_metvars3d
character(len=max_varname_length),dimension(:),allocatable:: name_chemvars3d
@@ -115,10 +132,13 @@ module gsi_rfv3io_mod
private
! set subroutines to public
public :: gsi_rfv3io_get_grid_specs
+ public :: gsi_rfv3io_get_ens_grid_specs
public :: gsi_fv3ncdf_read
public :: gsi_fv3ncdf_read_v1
public :: gsi_fv3ncdf_readuv
public :: gsi_fv3ncdf_readuv_v1
+ public :: gsi_fv3ncdf_read_ens_parallel_over_ens
+ public :: gsi_fv3ncdf_readuv_ens_parallel_over_ens
public :: read_fv3_files
public :: read_fv3_netcdf_guess
public :: wrfv3_netcdf
@@ -127,17 +147,18 @@ module gsi_rfv3io_mod
public :: mype_u,mype_v,mype_t,mype_q,mype_p,mype_oz,mype_ql
public :: mype_qi,mype_qr,mype_qs,mype_qg,mype_qnr,mype_w
public :: k_slmsk,k_tsea,k_vfrac,k_vtype,k_stype,k_zorl,k_smc,k_stc
- public :: k_snwdph,k_f10m,mype_2d,n2d,k_orog,k_psfc,k_t2m,k_q2m
+ public :: k_snwdph,k_f10m,mype_2d,n2d,k_orog,k_psfc,k_t2m,k_q2m,k_howv,k_gust
public :: ijns,ijns2d,displss,displss2d,ijnz,displsz_g
public :: fv3lam_io_dynmetvars3d_nouv,fv3lam_io_tracermetvars3d_nouv
public :: fv3lam_io_tracerchemvars3d_nouv,fv3lam_io_tracersmokevars3d_nouv
+ public :: fv3lam_io_phymetvars3d_nouv
public :: fv3lam_io_dynmetvars2d_nouv,fv3lam_io_tracermetvars2d_nouv
integer(i_kind) mype_u,mype_v,mype_t,mype_q,mype_p,mype_delz,mype_oz,mype_ql
integer(i_kind) mype_qi,mype_qr,mype_qs,mype_qg,mype_qnr,mype_w
integer(i_kind) k_slmsk,k_tsea,k_vfrac,k_vtype,k_stype,k_zorl,k_smc,k_stc
- integer(i_kind) k_snwdph,k_f10m,mype_2d,n2d,k_orog,k_psfc,k_t2m,k_q2m
+ integer(i_kind) k_snwdph,k_f10m,mype_2d,n2d,k_orog,k_psfc,k_t2m,k_q2m,k_howv,k_gust
parameter( &
k_f10m =1, & !fact10
k_stype=2, & !soil_type
@@ -152,12 +173,15 @@ module gsi_rfv3io_mod
k_t2m =11, & ! 2 m T
k_q2m =12, & ! 2 m Q
k_orog =13, & !terrain
- n2d=13 )
+ k_howv =14, & ! significant wave height (aka howv in GSI)
+ k_gust =15, & ! wind gust (aka gust in GSI)
+ n2d=15 )
logical :: grid_reverse_flag
character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_io_dynmetvars3d_nouv
! copy of cvars3d excluding uv 3-d fields
character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_io_tracermetvars3d_nouv
! copy of cvars3d excluding uv 3-d fields
+ character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_io_phymetvars3d_nouv
character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_io_tracerchemvars3d_nouv
character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_io_tracersmokevars3d_nouv
! copy of cvars3d excluding uv 3-d fields
@@ -169,17 +193,21 @@ module gsi_rfv3io_mod
!to define names in gsibundle
character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_names_gsibundle_tracer_nouv
!to define names in gsibundle
+ character(len=max_varname_length),allocatable,dimension(:) :: fv3lam_names_gsibundle_phyvar_nouv
type(gsi_bundle):: gsibundle_fv3lam_dynvar_nouv
type(gsi_bundle):: gsibundle_fv3lam_tracer_nouv
+ type(gsi_bundle):: gsibundle_fv3lam_phyvar_nouv
type(gsi_bundle):: gsibundle_fv3lam_tracerchem_nouv
type(gsi_bundle):: gsibundle_fv3lam_tracersmoke_nouv
contains
subroutine fv3regfilename_init(this,it)
implicit None
+
class(type_fv3regfilenameg),intent(inout):: this
+ integer(i_kind), intent(in ) :: it
+
character(255):: filename
- integer(i_kind),intent(in) :: it
if (it == ntguessig) then
this%grid_spec='fv3_grid_spec'
else
@@ -204,6 +232,12 @@ subroutine fv3regfilename_init(this,it)
write(filename,"(A11,I2.2)") 'fv3_tracer_',ifilesig(it)
this%tracers=trim(filename)
endif
+ if (it == ntguessig) then
+ this%phyvars='fv3_phyvars'
+ else
+ write(filename,"(A12,I2.2)") 'fv3_phyvars_',ifilesig(it)
+ this%phyvars=trim(filename)
+ endif
if (it == ntguessig) then
this%sfcdata='fv3_sfcdata'
else
@@ -263,11 +297,12 @@ subroutine gsi_rfv3io_get_grid_specs(ierr)
use mpimod, only: mpi_comm_world,mpi_itype,mpi_rtype
implicit none
+ integer(i_kind),intent( out) :: ierr
+
integer(i_kind) gfile_grid_spec
character(:),allocatable :: grid_spec
character(:),allocatable :: ak_bk
character(len=:),allocatable :: coupler_res_filenam
- integer(i_kind),intent( out) :: ierr
integer(i_kind) i,k,ndimensions,iret,nvariables,nattributes,unlimiteddimid
integer(i_kind) len,gfile_loc
character(len=max_varname_length) :: name
@@ -480,6 +515,164 @@ subroutine gsi_rfv3io_get_grid_specs(ierr)
return
end subroutine gsi_rfv3io_get_grid_specs
+subroutine gsi_rfv3io_get_ens_grid_specs(grid_spec,ierr)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: gsi_rfv3io_get_ens_grid_specs
+! modified from gsi_rfv3io_get_grid_specs
+! pgrmmr: parrish org: np22 date: 2017-04-03
+!
+! abstract: obtain grid dimensions nx,ny and grid definitions
+! grid_x,grid_xt,grid_y,grid_yt,grid_lon,grid_lont,grid_lat,grid_latt
+! nz,ak(nz),bk(nz)
+!
+! program history log:
+! 2017-04-03 parrish - initial documentation
+! 2017-10-10 wu - setup A grid and interpolation coeff with generate_anl_grid
+! 2018-02-16 wu - read in time info from file coupler.res
+! read in lat, lon at the center and corner of the grid cell
+! from file fv3_grid_spec, and vertical grid infor from file
+! fv3_akbk
+! setup A grid and interpolation/rotation coeff
+! input argument list:
+! grid_spec
+! ak_bk
+! lendian_out
+!
+! output argument list:
+! ierr
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+ use netcdf, only: nf90_open,nf90_close,nf90_get_var,nf90_noerr
+ use netcdf, only: nf90_nowrite,nf90_mpiio,nf90_inquire,nf90_inquire_dimension
+ use netcdf, only: nf90_inquire_variable
+ use mpimod, only: mype
+ use mod_fv3_lola, only: definecoef_regular_grids
+ use gridmod, only:nlon_regionalens,nlat_regionalens
+ use gridmod, only:grid_type_fv3_regional
+ use kinds, only: i_kind,r_kind
+ use constants, only: half,zero
+ use mpimod, only: mpi_comm_world,mpi_itype,mpi_rtype
+ implicit none
+ character(:),allocatable,intent(in ) :: grid_spec
+ integer(i_kind), intent( out) :: ierr
+
+ integer(i_kind) gfile_grid_spec
+ integer(i_kind) k,ndimensions,iret,nvariables,nattributes,unlimiteddimid
+ integer(i_kind) gfile_loc,len
+ character(len=128) :: name
+ integer(i_kind) :: nio,nylen
+ integer(i_kind),allocatable :: gfile_loc_layout(:)
+ character(len=180) :: filename_layout
+ integer(i_kind) imiddle,jmiddle,grid_ens_type_fv3_regional
+
+
+ iret=nf90_open(trim(grid_spec),nf90_nowrite,gfile_grid_spec)
+ if(iret/=nf90_noerr) then
+ write(6,*)' problem opening1 ',trim(grid_spec),', Status = ',iret
+ ierr=1
+ return
+ endif
+ iret=nf90_inquire(gfile_grid_spec,ndimensions,nvariables,nattributes,unlimiteddimid)
+ gfile_loc=gfile_grid_spec
+ do k=1,ndimensions
+ iret=nf90_inquire_dimension(gfile_loc,k,name,len)
+ if(trim(name)=='grid_xt') nxens=len
+ if(trim(name)=='grid_yt') nyens=len
+ enddo
+ allocate(grid_lat(nxens+1,nyens+1))
+ allocate(grid_lon(nxens+1,nyens+1))
+ allocate(grid_latt(nxens,nyens))
+ allocate(grid_lont(nxens,nyens))
+ do k=ndimensions+1,nvariables
+ iret=nf90_inquire_variable(gfile_loc,k,name,len)
+ if(trim(name)=='grid_lat') then
+ iret=nf90_get_var(gfile_loc,k,grid_lat)
+ endif
+ if(trim(name)=='grid_lon') then
+ iret=nf90_get_var(gfile_loc,k,grid_lon)
+ endif
+ if(trim(name)=='grid_latt') then
+ iret=nf90_get_var(gfile_loc,k,grid_latt)
+ endif
+ if(trim(name)=='grid_lont') then
+ iret=nf90_get_var(gfile_loc,k,grid_lont)
+ endif
+ enddo
+ iret=nf90_close(gfile_loc)
+
+ nlon_regionalens=nxens
+ nlat_regionalens=nyens
+ allocate(ny_layout_lenens(0:fv3_io_layout_y-1))
+ allocate(ny_layout_bens(0:fv3_io_layout_y-1))
+ allocate(ny_layout_eens(0:fv3_io_layout_y-1))
+ ny_layout_lenens=nyens
+ ny_layout_bens=0
+ ny_layout_eens=0
+ if(fv3_io_layout_y > 1) then
+ allocate(gfile_loc_layout(0:fv3_io_layout_y-1))
+ do nio=0,fv3_io_layout_y-1
+ write(filename_layout,'(a,a,I4.4)') trim(grid_spec),'.',nio
+ iret=nf90_open(filename_layout,nf90_nowrite,gfile_loc_layout(nio))
+ if(iret/=nf90_noerr) then
+ write(6,*)' problem opening ',trim(filename_layout),', Status =',iret
+ ierr=1
+ return
+ endif
+ iret=nf90_inquire(gfile_loc_layout(nio),ndimensions,nvariables,nattributes,unlimiteddimid)
+ do k=1,ndimensions
+ iret=nf90_inquire_dimension(gfile_loc_layout(nio),k,name,len)
+ if(trim(name)=='grid_yt') ny_layout_lenens(nio)=len
+ enddo
+ iret=nf90_close(gfile_loc_layout(nio))
+ enddo
+ deallocate(gfile_loc_layout)
+! figure out begin and end of each subdomain restart file
+ nylen=0
+ do nio=0,fv3_io_layout_y-1
+ ny_layout_bens(nio)=nylen + 1
+ nylen=nylen+ny_layout_lenens(nio)
+ ny_layout_eens(nio)=nylen
+ enddo
+ endif
+ if(mype==0)write(6,*),'nxens,nyens=',nxens,nyens
+ if(mype==0)write(6,*),'ny_layout_lenens=',ny_layout_lenens
+ if(mype==0)write(6,*),'ny_layout_bens=',ny_layout_bens
+ if(mype==0)write(6,*),'ny_layout_eens=',ny_layout_eens
+
+ imiddle=nxens/2
+ jmiddle=nyens/2
+ if( (grid_latt(imiddle,1) < grid_latt(imiddle,nyens)) .and. &
+ (grid_lont(1,jmiddle) < grid_lont(nxens,jmiddle)) ) then
+ grid_ens_type_fv3_regional = 2
+ else
+ grid_ens_type_fv3_regional = 1
+ endif
+! check the grid type
+ if( grid_type_fv3_regional == grid_ens_type_fv3_regional ) then
+ if(mype==0) write(6,*) 'Ensemble has the same orientation as the control, Cool!'
+ else
+ write(6,*) 'Warning! Ensemble has a different orientation as the control. This case needs further tests, Abort!'
+ call stop2(678)
+ endif
+!
+ if(grid_type_fv3_regional == 2) then
+ call reverse_grid_r(grid_lont,nxens,nyens,1)
+ call reverse_grid_r(grid_latt,nxens,nyens,1)
+ call reverse_grid_r(grid_lon,nxens+1,nyens+1,1)
+ call reverse_grid_r(grid_lat,nxens+1,nyens+1,1)
+ endif
+
+ call definecoef_regular_grids(nxens,nyens,grid_lon,grid_lont,grid_lat,grid_latt)
+ deallocate (grid_lon,grid_lat,grid_lont,grid_latt)
+ return
+end subroutine gsi_rfv3io_get_ens_grid_specs
+
+
subroutine read_fv3_files(mype)
!$$$ subprogram documentation block
! . . . .
@@ -522,7 +715,7 @@ subroutine read_fv3_files(mype)
! Declare local variables
logical(4) fexist
character(6) filename
- character(14) filenames
+ character(19) filenames
integer(i_kind) in_unit
integer(i_kind) i,j,iwan,npem1
integer(i_kind) nhr_half
@@ -557,11 +750,19 @@ subroutine read_fv3_files(mype)
in_unit=15
iwan=0
!WWWWWW setup for one first guess file for now
- do i=0,9 !place holder for FGAT
+ do i=0,9 !place holder for FGAT
if ( i == 6 ) then
- write(filenames,"(A11)") 'fv3_dynvars'
+ if(fv3_io_layout_y > 1) then
+ write(filenames,"(A16)") 'fv3_dynvars.0000'
+ else
+ write(filenames,"(A11)") 'fv3_dynvars'
+ endif
else
- write(filenames,"(A12,I2.2)") 'fv3_dynvars_',i
+ if(fv3_io_layout_y > 1) then
+ write(filenames,"(A17,I2.2)") 'fv3_dynvars.0000_',i
+ else
+ write(filenames,"(A12,I2.2)") 'fv3_dynvars_',i
+ endif
endif
INQUIRE(FILE=filenames, EXIST=fexist)
if(.not.fexist) cycle
@@ -740,6 +941,11 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
!
! abstract: read guess for FV3 regional model
! program history log:
+! 2022-04-01 Y. Wang and X. Wang - add capability to read reflectivity
+! for direct radar EnVar DA using reflectivity as state
+! variable, poc: xuguang.wang@ou.edu
+! 2023-07-30 Zhao - added code to read significant wave height (howv) field
+! from the 2D fv3-lam firstguess file (fv3_sfcdata).
! attributes:
! language: f90
! machine: ibm RS/6000 SP
@@ -768,14 +974,16 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
use gsi_metguess_mod, only: gsi_metguess_get
use netcdf, only:nf90_open,nf90_close,nf90_inquire,nf90_nowrite, nf90_format_netcdf4
use gsi_chemguess_mod, only: gsi_chemguess_get
+ use obsmod, only: if_model_dbz,if_model_fed
implicit none
type (type_fv3regfilenameg),intent (in) :: fv3filenamegin(:)
+
integer(i_kind) :: it
character(len=24),parameter :: myname = 'read_fv3_netcdf_guess'
integer(i_kind) k,i,j
- integer(i_kind) ier,istatus
+ integer(i_kind) ier,istatus,ivar
real(r_kind),dimension(:,:),pointer::ges_ps=>NULL()
real(r_kind),dimension(:,:),pointer::ges_ps_readin=>NULL()
real(r_kind),dimension(:,:),pointer::ges_z=>NULL()
@@ -788,6 +996,8 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
real(r_kind),pointer,dimension(:,:,:):: ges_delp =>NULL()
real(r_kind),dimension(:,:),pointer::ges_t2m=>NULL()
real(r_kind),dimension(:,:),pointer::ges_q2m=>NULL()
+ real(r_kind),dimension(:,:),pointer::ges_howv=>NULL()
+ real(r_kind),dimension(:,:),pointer::ges_gust=>NULL()
real(r_kind),dimension(:,:,:),pointer::ges_ql=>NULL()
real(r_kind),dimension(:,:,:),pointer::ges_qi=>NULL()
@@ -797,7 +1007,8 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
real(r_kind),dimension(:,:,:),pointer::ges_qg=>NULL()
real(r_kind),dimension(:,:,:),pointer::ges_qnr=>NULL()
real(r_kind),dimension(:,:,:),pointer::ges_w=>NULL()
-
+ real(r_kind),dimension(:,:,:),pointer::ges_dbz=>NULL()
+ real(r_kind),dimension(:,:,:),pointer::ges_fed=>NULL()
real(r_kind),dimension(:,:,:),pointer::ges_aalj=>NULL()
real(r_kind),dimension(:,:,:),pointer::ges_acaj=>NULL()
@@ -890,8 +1101,8 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
integer(i_kind),dimension(:,:),allocatable:: lnames
integer(i_kind),dimension(:,:),allocatable:: uvlnames
integer(i_kind):: inner_vars,numfields
- integer(i_kind):: ndynvario2d,ntracerio2d,ilev,jdynvar,jtracer
- integer(i_kind):: iuv,ndynvario3d,ntracerio3d
+ integer(i_kind):: ndynvario2d,ntracerio2d,ilev,jdynvar,jtracer,jphyvar
+ integer(i_kind):: iuv,ndynvario3d,ntracerio3d,nphyvario3d
integer(i_kind):: ntracerchemio3d,ntracersmokeio3d
integer(i_kind):: loc_id,ncfmt
@@ -957,6 +1168,7 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
iuv=0
ndynvario3d=0
ntracerio3d=0
+ nphyvario3d=0
do i=1,size(name_metvars3d)
vartem=trim(name_metvars3d(i))
if(trim(vartem)=='u'.or.trim(vartem)=='v') then
@@ -967,6 +1179,8 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
ndynvario3d=ndynvario3d+1
else if (ifindstrloc(vartracers,trim(vartem))> 0) then
ntracerio3d=ntracerio3d+1
+ else if (ifindstrloc(varphyvars,trim(vartem))> 0) then
+ nphyvario3d=nphyvario3d+1
else
write(6,*)'the metvarname1 ',trim(vartem),' has not been considered yet, stop'
call stop2(333)
@@ -978,6 +1192,13 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
write(6,*)"the set up for met variable is not as expected, abort"
call stop2(222)
endif
+
+ ivar=0 ; if (if_model_dbz) ivar=ivar+1; if(if_model_fed) ivar=ivar+1
+ if ( ivar > nphyvario3d ) then
+ write(6,*)"the set up for met variable (dbz and fed in phyvar) is not as expected,abort"
+ call stop2(223)
+ end if
+
if (fv3sar_bg_opt == 0.and.ifindstrloc(name_metvars3d,'delp') <= 0)then
ndynvario3d=ndynvario3d+1 ! for delp
endif
@@ -987,6 +1208,7 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
if (l_reg_update_hydro_delz.and.fv3sar_bg_opt==0) ndynvario3d=ndynvario3d+1 ! for delzinc
allocate(fv3lam_io_dynmetvars3d_nouv(ndynvario3d))
allocate(fv3lam_io_tracermetvars3d_nouv(ntracerio3d))
+ allocate(fv3lam_io_phymetvars3d_nouv(nphyvario3d))
if (laeroana_fv3cmaq) then
allocate(fv3lam_io_tracerchemvars3d_nouv(naero_cmaq_fv3+7))
@@ -998,6 +1220,7 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
jdynvar=0
jtracer=0
+ jphyvar=0
do i=1,size(name_metvars3d)
vartem=trim(name_metvars3d(i))
if(.not.(trim(vartem)=='u'.or.trim(vartem)=='v'.or.trim(vartem)=='iqr')) then
@@ -1012,9 +1235,11 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
else if (ifindstrloc(vartracers,trim(vartem)) > 0) then
jtracer=jtracer+1
fv3lam_io_tracermetvars3d_nouv(jtracer)=trim(vartem)
+ else if (ifindstrloc(varphyvars,trim(vartem)) > 0) then
+ jphyvar=jphyvar+1
+ fv3lam_io_phymetvars3d_nouv(jphyvar)=trim(vartem)
else
write(6,*)'the metvarname ',vartem,' is not expected, stop'
- call flush(6)
call stop2(333)
endif
endif
@@ -1027,14 +1252,14 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
jdynvar=jdynvar+1
fv3lam_io_dynmetvars3d_nouv(jdynvar)="delzinc"
endif
- if(jdynvar /= ndynvario3d.or.jtracer /= ntracerio3d ) then
+ if(jdynvar /= ndynvario3d.or.jtracer /= ntracerio3d.or.jphyvar /= nphyvario3d ) then
write(6,*)'ndynvario3d is not as expected, stop'
- call flush(6)
call stop2(333)
endif
if(mype == 0) then
write(6,*) ' fv3lam_io_dynmetvars3d_nouv is ',(trim(fv3lam_io_dynmetvars3d_nouv(i)),i=1,ndynvario3d)
write(6,*) ' fv3lam_io_tracermevars3d_nouv is ',(trim(fv3lam_io_tracermetvars3d_nouv(i)),i=1,ntracerio3d)
+ write(6,*) ' fv3lam_io_phymetvars3d_nouv is ',(trim(fv3lam_io_phymetvars3d_nouv(i)),i=1,nphyvario3d)
endif
ndynvario2d=0
@@ -1047,9 +1272,11 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
else if (ifindstrloc(vartracers,trim(vartem)) > 0) then
ntracerio2d=ntracerio2d+1
else if(trim(vartem)=='z') then
- write(6,*)'the metvarname ',trim(vartem),' will be dealt separately'
+ if(mype == 0) write(6,*)'the metvarname ',trim(vartem),' will be dealt separately'
else if(trim(vartem)=='t2m') then
else if(trim(vartem)=='q2m') then
+ else if(trim(vartem)=='howv') then
+ else if(trim(vartem)=='gust') then
else
write(6,*)'the metvarname2 ',trim(vartem),' has not been considered yet, stop'
call stop2(333)
@@ -1057,7 +1284,9 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
endif
end do
if (ndynvario2d > 0) then
- allocate(fv3lam_io_dynmetvars2d_nouv(ndynvario2d))
+ if (.not. allocated(fv3lam_io_dynmetvars2d_nouv)) then
+ allocate(fv3lam_io_dynmetvars2d_nouv(ndynvario2d))
+ end if
endif
if (ntracerio2d > 0) then
allocate(fv3lam_io_tracermetvars2d_nouv(ntracerio2d))
@@ -1067,7 +1296,8 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
do i=1,size(name_metvars2d)
vartem=trim(name_metvars2d(i))
if(.not.( (trim(vartem)=='ps'.and.fv3sar_bg_opt==0).or.(trim(vartem)=="z") &
- .or.(trim(vartem)=="t2m").or.(trim(vartem)=="q2m"))) then !z is treated separately
+ .or.(trim(vartem)=="t2m").or.(trim(vartem)=="q2m") &
+ .or.(trim(vartem)=="howv").or.(trim(vartem)=="gust"))) then ! z is treated separately
if (ifindstrloc(vardynvars,trim(vartem)) > 0) then
jdynvar=jdynvar+1
fv3lam_io_dynmetvars2d_nouv(jdynvar)=trim(vartem)
@@ -1084,7 +1314,7 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
if (allocated(fv3lam_io_dynmetvars2d_nouv)) &
write(6,*)' fv3lam_io_dynmetvars2d_nouv is ',(trim(fv3lam_io_dynmetvars2d_nouv(i)), i=1,ndynvario2d)
if (allocated(fv3lam_io_tracermetvars2d_nouv))&
- write(6,*)'fv3lam_io_dynmetvars2d_nouv is ',(trim(fv3lam_io_dynmetvars2d_nouv(i)),i=1,ntracerio3d)
+ write(6,*)'fv3lam_io_tracermetvars2d_nouv is ',(trim(fv3lam_io_tracermetvars2d_nouv(i)),i=1,ntracerio2d)
endif
if (laeroana_fv3cmaq) then
@@ -1132,7 +1362,6 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
else
if (trim(vartem) /= "pm2_5")then
write(6,*)'the chemvarname ',vartem,' is not in aeronames_smoke_fv3 !!!'
- call flush(6)
endif
endif
enddo
@@ -1165,6 +1394,11 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
ntracerio2d=0
endif
+ if( allocated(fv3lam_io_phymetvars3d_nouv) )then
+ call gsi_bundlecreate(gsibundle_fv3lam_phyvar_nouv,GSI_MetGuess_Bundle(it)%grid,'gsibundle_fv3lam_phyvar_nouv',istatus, &
+ names3d=fv3lam_io_phymetvars3d_nouv)
+ end if
+
if (laeroana_fv3cmaq) then
if (allocated(fv3lam_io_tracerchemvars3d_nouv) ) then
call gsi_bundlecreate(gsibundle_fv3lam_tracerchem_nouv,GSI_ChemGuess_Bundle(it)%grid,'gsibundle_fv3lam_tracerchem_nouv',istatus, &
@@ -1254,6 +1488,22 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
endif
+ if ( if_model_dbz .or. if_model_fed )then
+ inner_vars=1
+ numfields=inner_vars*(nphyvario3d*grd_a%nsig)
+ deallocate(lnames,names)
+ allocate(lnames(1,numfields),names(1,numfields))
+ ilev=1
+ do i=1,nphyvario3d
+ do k=1,grd_a%nsig
+ lnames(1,ilev)=k
+ names(1,ilev)=trim(fv3lam_io_phymetvars3d_nouv(i))
+ ilev=ilev+1
+ enddo
+ enddo
+ call general_sub2grid_create_info(grd_fv3lam_phyvar_ionouv,inner_vars,grd_a%nlat,&
+ grd_a%nlon,grd_a%nsig,numfields,regional,names=names,lnames=lnames)
+ end if
inner_vars=2
numfields=grd_a%nsig
@@ -1279,15 +1529,21 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'tv' ,ges_tv ,istatus );ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'q' ,ges_q ,istatus );ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'oz' ,ges_oz ,istatus );ier=ier+istatus
- if (l_use_dbz_directDA) then
+ if (l_use_dbz_directDA .or. nphyvario3d > 0) then
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'ql' ,ges_ql ,istatus );ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'qi' ,ges_qi ,istatus );ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'qr' ,ges_qr ,istatus );ier=ier+istatus
- call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'iqr' ,ges_iqr ,istatus );ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'qs' ,ges_qs ,istatus );ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'qg' ,ges_qg ,istatus );ier=ier+istatus
- call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'qnr',ges_qnr ,istatus );ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'w' , ges_w ,istatus );ier=ier+istatus
+ if (l_use_dbz_directDA) then
+ call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'iqr' ,ges_iqr ,istatus );ier=ier+istatus
+ call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'qnr',ges_qnr ,istatus );ier=ier+istatus
+ end if
+ if(if_model_dbz) &
+ call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'dbz' , ges_dbz ,istatus );ier=ier+istatus
+ if(if_model_fed) &
+ call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'fed' , ges_fed ,istatus );ier=ier+istatus
end if
if (ier/=0) call die(trim(myname),'cannot get pointers for fv3 met-fields, ier =',ier)
@@ -1297,6 +1553,19 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it),'t2m',ges_t2m,istatus );ier=ier+istatus
if (ier/=0) call die(trim(myname),'cannot get pointers for t2m,ier=',ier)
endif
+
+!--- significant wave height (howv)
+ if ( i_howv_3dda == 1 ) then
+ call GSI_BundleGetPointer(GSI_MetGuess_Bundle(it),'howv',ges_howv,istatus ); ier=ier+istatus
+ if (ier/=0) call die(trim(myname),'cannot get pointers for howv, ier=',ier)
+ endif
+
+!--- wind gust (gust)
+ if ( i_gust_3dda == 1 ) then
+ call GSI_BundleGetPointer(GSI_MetGuess_Bundle(it),'gust',ges_gust,istatus ); ier=ier+istatus
+ if (ier/=0) call die(trim(myname),'cannot get pointers for gust, ier=',ier)
+ endif
+
if(mype == 0 ) then
call check(nf90_open(fv3filenamegin(it)%dynvars,nf90_nowrite,loc_id))
call check(nf90_inquire(loc_id,formatNum=ncfmt))
@@ -1333,36 +1602,40 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
end if
if( fv3sar_bg_opt == 0) then
- call gsi_fv3ncdf_readuv(grd_fv3lam_uv,ges_u,ges_v,fv3filenamegin(it))
+ call gsi_fv3ncdf_readuv(grd_fv3lam_uv,ges_u,ges_v,fv3filenamegin(it),.false.)
else
- call gsi_fv3ncdf_readuv_v1(grd_fv3lam_uv,ges_u,ges_v,fv3filenamegin(it))
+ call gsi_fv3ncdf_readuv_v1(grd_fv3lam_uv,ges_u,ges_v,fv3filenamegin(it),.false.)
endif
if( fv3sar_bg_opt == 0) then
call gsi_fv3ncdf_read(grd_fv3lam_dynvar_ionouv,gsibundle_fv3lam_dynvar_nouv &
- & ,fv3filenamegin(it)%dynvars,fv3filenamegin(it))
+ & ,fv3filenamegin(it)%dynvars,fv3filenamegin(it),.false.)
call gsi_fv3ncdf_read(grd_fv3lam_tracer_ionouv,gsibundle_fv3lam_tracer_nouv &
- & ,fv3filenamegin(it)%tracers,fv3filenamegin(it))
+ & ,fv3filenamegin(it)%tracers,fv3filenamegin(it),.false.)
+ if( nphyvario3d > 0 )then
+ call gsi_fv3ncdf_read(grd_fv3lam_phyvar_ionouv,gsibundle_fv3lam_phyvar_nouv &
+ & ,fv3filenamegin(it)%phyvars,fv3filenamegin(it),.false.)
+ end if
if (laeroana_fv3cmaq) then
call gsi_fv3ncdf_read(grd_fv3lam_tracerchem_ionouv,gsibundle_fv3lam_tracerchem_nouv &
- & ,fv3filenamegin(it)%tracers,fv3filenamegin(it))
+ & ,fv3filenamegin(it)%tracers,fv3filenamegin(it),.false.)
endif
if (laeroana_fv3smoke) then
call gsi_fv3ncdf_read(grd_fv3lam_tracersmoke_ionouv,gsibundle_fv3lam_tracersmoke_nouv &
- & ,fv3filenamegin(it)%tracers,fv3filenamegin(it))
+ & ,fv3filenamegin(it)%tracers,fv3filenamegin(it),.false.)
endif
else
call gsi_fv3ncdf_read_v1(grd_fv3lam_dynvar_ionouv,gsibundle_fv3lam_dynvar_nouv &
- & ,fv3filenamegin(it)%dynvars,fv3filenamegin(it))
+ & ,fv3filenamegin(it)%dynvars,fv3filenamegin(it),.false.)
call gsi_fv3ncdf_read_v1(grd_fv3lam_tracer_ionouv,gsibundle_fv3lam_tracer_nouv &
- & ,fv3filenamegin(it)%tracers,fv3filenamegin(it))
+ & ,fv3filenamegin(it)%tracers,fv3filenamegin(it),.false.)
if (laeroana_fv3cmaq) then
call gsi_fv3ncdf_read_v1(grd_fv3lam_tracerchem_ionouv,gsibundle_fv3lam_tracerchem_nouv &
- & ,fv3filenamegin(it)%tracers,fv3filenamegin(it))
+ & ,fv3filenamegin(it)%tracers,fv3filenamegin(it),.false.)
endif
if (laeroana_fv3smoke) then
call gsi_fv3ncdf_read_v1(grd_fv3lam_tracersmoke_ionouv,gsibundle_fv3lam_tracersmoke_nouv &
- & ,fv3filenamegin(it)%tracers,fv3filenamegin(it))
+ & ,fv3filenamegin(it)%tracers,fv3filenamegin(it),.false.)
endif
endif
@@ -1438,7 +1711,9 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
if (laeroana_fv3smoke) then
call gsi_copy_bundle(gsibundle_fv3lam_tracersmoke_nouv,GSI_ChemGuess_Bundle(it))
endif
-
+ if ( nphyvario3d > 0 ) then
+ call gsi_copy_bundle(gsibundle_fv3lam_phyvar_nouv,GSI_MetGuess_Bundle(it))
+ end if
call GSI_BundleGetPointer ( gsibundle_fv3lam_dynvar_nouv, 'tsen' ,ges_tsen_readin ,istatus );ier=ier+istatus
!! tsen2tv !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
do k=1,nsig
@@ -1473,7 +1748,8 @@ subroutine read_fv3_netcdf_guess(fv3filenamegin)
endif
- call gsi_fv3ncdf2d_read(fv3filenamegin(it),it,ges_z,ges_t2m,ges_q2m)
+ call gsi_fv3ncdf2d_read(fv3filenamegin(it),it,ges_z,ges_t2m,ges_q2m, &
+ ges_howv,ges_gust)
if(i_use_2mq4b > 0 .and. i_use_2mt4b > 0 ) then
! Convert 2m guess mixing ratio to specific humidity
@@ -1709,7 +1985,8 @@ end subroutine gsi_bundlegetpointer_fv3lam_tracerchem_nouv
end subroutine read_fv3_netcdf_guess
-subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
+subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m, &
+ ges_howv,ges_gust)
!$$$ subprogram documentation block
! . . . .
! subprogram: gsi_fv3ncdf2d_read
@@ -1718,6 +1995,10 @@ subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
! abstract: read in 2d fields from fv3_sfcdata file in mype_2d
! Scatter the field to each PE
! program history log:
+! 2023-02-14 Hu - Bug fix for read in subdomain surface restart files
+! 2023-07-30 Zhao - added IO to read significant wave height (howv) from 2D FV3-LAM
+! firstguess file (fv3_sfcdata)
+!
! input argument list:
! it - time index for 2d fields
!
@@ -1730,7 +2011,8 @@ subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
!
!$$$ end documentation block
use kinds, only: r_kind,i_kind
- use mpimod, only: ierror,mpi_comm_world,npe,mpi_rtype,mype
+ use mpimod, only: ierror,mpi_comm_world,npe,mpi_rtype,mype,mpi_itype
+ use mpeu_util, only: die
use guess_grids, only: fact10,soil_type,veg_frac,veg_type,sfc_rough, &
sfct,sno,soil_temp,soil_moi,isli
use gridmod, only: lat2,lon2,itotsub,ijn_s
@@ -1738,18 +2020,24 @@ subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
use netcdf, only: nf90_open,nf90_close,nf90_get_var,nf90_noerr
use netcdf, only: nf90_nowrite,nf90_inquire,nf90_inquire_dimension
use netcdf, only: nf90_inquire_variable
+ use netcdf, only: nf90_inq_varid
+ use netcdf, only: nf90_noerr
use mod_fv3_lola, only: fv3_h_to_ll,nxa,nya
use constants, only: grav
+ use constants, only: zero
implicit none
- integer(i_kind),intent(in) :: it
- real(r_kind),intent(in),dimension(:,:),pointer::ges_z
- real(r_kind),intent(in),dimension(:,:),pointer::ges_t2m
- real(r_kind),intent(in),dimension(:,:),pointer::ges_q2m
+ integer(i_kind), intent(in) :: it
+ real(r_kind), intent(in),dimension(:,:),pointer::ges_z
+ real(r_kind), intent(in),dimension(:,:),pointer::ges_t2m
+ real(r_kind), intent(in),dimension(:,:),pointer::ges_q2m
+ real(r_kind), intent(in),dimension(:,:),pointer::ges_howv
+ real(r_kind), intent(in),dimension(:,:),pointer::ges_gust
type (type_fv3regfilenameg),intent(in) :: fv3filenamegin
+
character(len=max_varname_length) :: name
- integer(i_kind),allocatable,dimension(:):: dim_id,dim
+ integer(i_kind),allocatable,dimension(:):: dim
real(r_kind),allocatable,dimension(:):: work
real(r_kind),allocatable,dimension(:,:):: a
real(r_kind),allocatable,dimension(:,:,:):: sfcn2d
@@ -1760,6 +2048,9 @@ subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
integer(i_kind) kk,n,ns,j,ii,jj,mm1
character(len=:),allocatable :: sfcdata !='fv3_sfcdata'
character(len=:),allocatable :: dynvars !='fv3_dynvars'
+! for checking the existence of howv/gust in firstguess file
+ integer(i_kind) id_howv, id_gust
+ integer(i_kind) iret_bcast
! for io_layout > 1
real(r_kind),allocatable,dimension(:,:):: sfc_fulldomain
@@ -1767,6 +2058,9 @@ subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
integer(i_kind),allocatable :: gfile_loc_layout(:)
character(len=180) :: filename_layout
+! for sfc 2d vaiable exist or not
+ logical, dimension(n2d) :: sfc_var_exist
+
sfcdata= fv3filenamegin%sfcdata
dynvars= fv3filenamegin%dynvars
@@ -1775,6 +2069,13 @@ subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
allocate(work(itotsub*n2d))
allocate( sfcn2d(lat2,lon2,n2d))
+!-- initialisation of the array for howv/gust
+ sfcn2d(:,:,k_howv) = zero
+ sfcn2d(:,:,k_gust) = zero
+
+!-- initialisation of the array for sfc_var_exist
+ sfc_var_exist = .false.
+
if(mype==mype_2d ) then
allocate(sfc_fulldomain(nx,ny))
@@ -1802,33 +2103,84 @@ subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
iret=nf90_inquire_dimension(gfile_loc,k,name,len)
dim(k)=len
enddo
+
+!--- check the existence of significant wave height (howv) in 2D FV3-LAM firstguess file
+! if howv is set in anavinfo (as i_howv_3dda=1), then check its existence in firstguess,
+! but if it is not found in firstguess, then stop GSI run and set i_howv_3dda = 0.
+ if ( i_howv_3dda == 1 ) then
+ iret = nf90_inq_varid(gfile_loc,'howv',id_howv)
+ if ( iret /= nf90_noerr ) then
+ iret = nf90_inq_varid(gfile_loc,'HOWV',id_howv) ! double check with name in uppercase
+ end if
+ if ( iret /= nf90_noerr ) then
+ i_howv_3dda = 0 ! howv does not exist in firstguess, then stop GSI run.
+ call die('gsi_fv3ncdf2d_read','Warning: CANNOT find howv in firstguess, aborting..., iret = ', iret)
+ else
+ write(6,'(1x,A,1x,A,1x,A,1x,I4,1x,I4,1x,A,1x,I4.4,A)') 'gsi_fv3ncdf2d_read:: Found howv in firstguess ', &
+ trim(sfcdata), ', iret, varid = ',iret, id_howv,' (on pe: ', mype,').'
+ end if
+ end if
+!--- check the existence of wind gust (gust) in 2D FV3-LAM firstguess file
+! (similar as done above for howv)
+ if ( i_gust_3dda == 1 ) then
+ iret = nf90_inq_varid(gfile_loc,'gust',id_gust)
+ if ( iret /= nf90_noerr ) then
+ iret = nf90_inq_varid(gfile_loc,'GUST',id_gust) ! double check with name in uppercase
+ end if
+ if ( iret /= nf90_noerr ) then
+ i_gust_3dda = 0 ! gust does not exist in firstguess, then stop GSI run.
+ call die('gsi_fv3ncdf2d_read','Warning: CANNOT find gust in firstguess, aborting..., iret = ', iret)
+ else
+ write(6,'(1x,A,1x,A,1x,A,1x,I4,1x,I4,1x,A,1x,I4.4,A)') 'gsi_fv3ncdf2d_read:: Found gust in firstguess ', &
+ trim(sfcdata), ', iret, varid = ',iret, id_gust,' (on pe: ', mype,').'
+ end if
+ end if
+
!!!!!!!!!!!! read in 2d variables !!!!!!!!!!!!!!!!!!!!!!!!!!
do i=ndimensions+1,nvariables
iret=nf90_inquire_variable(gfile_loc,i,name,len)
if( trim(name)=='f10m'.or.trim(name)=='F10M' ) then
k=k_f10m
+ sfc_var_exist(k) = .true.
else if( trim(name)=='stype'.or.trim(name)=='STYPE' ) then
k=k_stype
+ sfc_var_exist(k) = .true.
else if( trim(name)=='vfrac'.or.trim(name)=='VFRAC' ) then
k=k_vfrac
+ sfc_var_exist(k) = .true.
else if( trim(name)=='vtype'.or.trim(name)=='VTYPE' ) then
k=k_vtype
+ sfc_var_exist(k) = .true.
else if( trim(name)=='zorl'.or.trim(name)=='ZORL' ) then
k=k_zorl
+ sfc_var_exist(k) = .true.
else if( trim(name)=='tsea'.or.trim(name)=='TSEA' ) then
k=k_tsea
+ sfc_var_exist(k) = .true.
else if( trim(name)=='sheleg'.or.trim(name)=='SHELEG' ) then
k=k_snwdph
- else if( trim(name)=='stc'.or.trim(name)=='STC' ) then
+ sfc_var_exist(k) = .true.
+ else if( trim(name)=='stc'.or.trim(name)=='tslb' ) then
k=k_stc
- else if( trim(name)=='smc'.or.trim(name)=='SMC' ) then
+ sfc_var_exist(k) = .true.
+ else if( trim(name)=='smc'.or.trim(name)=='smois' ) then
k=k_smc
+ sfc_var_exist(k) = .true.
else if( trim(name)=='SLMSK'.or.trim(name)=='slmsk' ) then
k=k_slmsk
+ sfc_var_exist(k) = .true.
else if( trim(name)=='T2M'.or.trim(name)=='t2m' ) then
k=k_t2m
+ sfc_var_exist(k) = .true.
else if( trim(name)=='Q2M'.or.trim(name)=='q2m' ) then
k=k_q2m
+ sfc_var_exist(k) = .true.
+ else if( trim(name)=='HOWV'.or.trim(name)=='howv' ) then
+ k=k_howv
+ sfc_var_exist(k) = .true.
+ else if( trim(name)=='GUST'.or.trim(name)=='gust' ) then
+ k=k_gust
+ sfc_var_exist(k) = .true.
else
cycle
endif
@@ -1837,40 +2189,24 @@ subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
write(*,*) "wrong dimension number ndim =",ndim
call stop2(119)
endif
- if(allocated(dim_id )) deallocate(dim_id )
- allocate(dim_id(ndim))
if(fv3_io_layout_y > 1) then
do nio=0,fv3_io_layout_y-1
- iret=nf90_inquire_variable(gfile_loc_layout(nio),i,dimids=dim_id)
- if(allocated(sfc )) deallocate(sfc )
- if(dim(dim_id(1)) == nx .and. dim(dim_id(2))==ny_layout_len(nio)) then
- if(ndim >=3) then
- allocate(sfc(dim(dim_id(1)),dim(dim_id(2)),dim(dim_id(3))))
- iret=nf90_get_var(gfile_loc_layout(nio),i,sfc)
- else if (ndim == 2) then
- allocate(sfc(dim(dim_id(1)),dim(dim_id(2)),1))
- iret=nf90_get_var(gfile_loc_layout(nio),i,sfc(:,:,1))
- endif
- else
- write(*,*) "Mismatch dimension in surfacei reading:",nx,ny_layout_len(nio),dim(dim_id(1)),dim(dim_id(2))
- call stop2(119)
- endif
- sfc_fulldomain(:,ny_layout_b(nio):ny_layout_e(nio))=sfc(:,:,1)
+ if(allocated(sfc )) deallocate(sfc )
+ allocate(sfc(nx,ny_layout_len(nio),1))
+ if(ndim >=3) then
+ iret=nf90_get_var(gfile_loc_layout(nio),i,sfc)
+ else if (ndim == 2) then
+ iret=nf90_get_var(gfile_loc_layout(nio),i,sfc(:,:,1))
+ endif
+ sfc_fulldomain(:,ny_layout_b(nio):ny_layout_e(nio))=sfc(:,:,1)
enddo
else
- iret=nf90_inquire_variable(gfile_loc,i,dimids=dim_id)
if(allocated(sfc )) deallocate(sfc )
- if(dim(dim_id(1)) == nx .and. dim(dim_id(2))==ny) then
- if(ndim >=3) then !the block of 10 lines is compied from GSL gsi.
- allocate(sfc(dim(dim_id(1)),dim(dim_id(2)),dim(dim_id(3))))
- iret=nf90_get_var(gfile_loc,i,sfc)
- else if (ndim == 2) then
- allocate(sfc(dim(dim_id(1)),dim(dim_id(2)),1))
- iret=nf90_get_var(gfile_loc,i,sfc(:,:,1))
- endif
- else
- write(*,*) "Mismatch dimension in surfacei reading:",nx,ny,dim(dim_id(1)),dim(dim_id(2))
- call stop2(119)
+ allocate(sfc(nx,ny,1))
+ if(ndim >=3) then
+ iret=nf90_get_var(gfile_loc,i,sfc)
+ else if (ndim == 2) then
+ iret=nf90_get_var(gfile_loc,i,sfc(:,:,1))
endif
sfc_fulldomain(:,:)=sfc(:,:,1)
endif
@@ -1931,20 +2267,18 @@ subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
do k=ndimensions+1,nvariables
iret=nf90_inquire_variable(gfile_loc,k,name,len)
if(trim(name)=='PHIS' .or. trim(name)=='phis' ) then
+ sfc_var_exist(k_orog) = .true.
iret=nf90_inquire_variable(gfile_loc,k,ndims=ndim)
- if(allocated(dim_id )) deallocate(dim_id )
- allocate(dim_id(ndim))
if(fv3_io_layout_y > 1) then
do nio=0,fv3_io_layout_y-1
- iret=nf90_inquire_variable(gfile_loc_layout(nio),k,dimids=dim_id)
if(allocated(sfc1 )) deallocate(sfc1 )
- allocate(sfc1(dim(dim_id(1)),dim(dim_id(2))) )
+ allocate(sfc1(nx,ny_layout_len(nio)) )
iret=nf90_get_var(gfile_loc_layout(nio),k,sfc1)
sfc_fulldomain(:,ny_layout_b(nio):ny_layout_e(nio))=sfc1
enddo
else
- iret=nf90_inquire_variable(gfile_loc,k,dimids=dim_id)
- allocate(sfc1(dim(dim_id(1)),dim(dim_id(2))) )
+ if(allocated(sfc1 )) deallocate(sfc1 )
+ allocate(sfc1(nx,ny) )
iret=nf90_get_var(gfile_loc,k,sfc1)
sfc_fulldomain=sfc1
endif
@@ -1975,10 +2309,17 @@ subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
end do
end do
- if(allocated(sfc1) .and. allocated(sfc))deallocate (dim_id,sfc,sfc1,dim)
+ if(allocated(sfc1) .and. allocated(sfc)) deallocate (sfc,sfc1)
+ if(allocated(dim)) deallocate (dim)
if(allocated(sfc_fulldomain)) deallocate (sfc_fulldomain)
endif ! mype
+!-- broadcast the updated i_howv_3dda, i_gust_3dda to all tasks (!!!!)
+ call mpi_bcast(i_howv_3dda, 1, mpi_itype, mype_2d, mpi_comm_world, iret_bcast)
+ call mpi_bcast(i_gust_3dda, 1, mpi_itype, mype_2d, mpi_comm_world, iret_bcast)
+
+!-- broadcast the updated sfc_var_exist to all tasks (!!!!)
+ call mpi_bcast(sfc_var_exist, n2d, mpi_itype, mype_2d, mpi_comm_world, iret_bcast)
!!!!!!! scatter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
call mpi_scatterv(work,ijns2d,displss2d,mpi_rtype,&
@@ -1986,20 +2327,26 @@ subroutine gsi_fv3ncdf2d_read(fv3filenamegin,it,ges_z,ges_t2m,ges_q2m)
deallocate ( work )
- fact10(:,:,it)=sfcn2d(:,:,k_f10m)
- soil_type(:,:,it)=sfcn2d(:,:,k_stype)
- veg_frac(:,:,it)=sfcn2d(:,:,k_vfrac)
- veg_type(:,:,it)=sfcn2d(:,:,k_vtype)
- sfc_rough(:,:,it)=sfcn2d(:,:,k_zorl)
- sfct(:,:,it)=sfcn2d(:,:,k_tsea)
- sno(:,:,it)=sfcn2d(:,:,k_snwdph)
- soil_temp(:,:,it)=sfcn2d(:,:,k_stc)
- soil_moi(:,:,it)=sfcn2d(:,:,k_smc)
- ges_z(:,:)=sfcn2d(:,:,k_orog)/grav
- isli(:,:,it)=nint(sfcn2d(:,:,k_slmsk))
+ if ( sfc_var_exist(k_f10m) ) fact10(:,:,it)=sfcn2d(:,:,k_f10m)
+ if ( sfc_var_exist(k_stype) ) soil_type(:,:,it)=sfcn2d(:,:,k_stype)
+ if ( sfc_var_exist(k_vfrac) ) veg_frac(:,:,it)=sfcn2d(:,:,k_vfrac)
+ if ( sfc_var_exist(k_vtype) ) veg_type(:,:,it)=sfcn2d(:,:,k_vtype)
+ if ( sfc_var_exist(k_zorl) ) sfc_rough(:,:,it)=sfcn2d(:,:,k_zorl)
+ if ( sfc_var_exist(k_tsea) ) sfct(:,:,it)=sfcn2d(:,:,k_tsea)
+ if ( sfc_var_exist(k_snwdph)) sno(:,:,it)=sfcn2d(:,:,k_snwdph)
+ if ( sfc_var_exist(k_stc) ) soil_temp(:,:,it)=sfcn2d(:,:,k_stc)
+ if ( sfc_var_exist(k_smc) ) soil_moi(:,:,it)=sfcn2d(:,:,k_smc)
+ if ( sfc_var_exist(k_orog) ) ges_z(:,:)=sfcn2d(:,:,k_orog)/grav
+ if ( sfc_var_exist(k_slmsk) ) isli(:,:,it)=nint(sfcn2d(:,:,k_slmsk))
if(i_use_2mq4b > 0 .and. i_use_2mt4b > 0 ) then
- ges_t2m(:,:)=sfcn2d(:,:,k_t2m)
- ges_q2m(:,:)=sfcn2d(:,:,k_q2m)
+ if ( sfc_var_exist(k_t2m) ) ges_t2m(:,:)=sfcn2d(:,:,k_t2m)
+ if ( sfc_var_exist(k_q2m) ) ges_q2m(:,:)=sfcn2d(:,:,k_q2m)
+ endif
+ if ( i_howv_3dda == 1 ) then
+ if ( sfc_var_exist(k_howv) ) ges_howv(:,:)=sfcn2d(:,:,k_howv)
+ endif
+ if ( i_gust_3dda == 1 ) then
+ if ( sfc_var_exist(k_gust) ) ges_gust(:,:)=sfcn2d(:,:,k_gust)
endif
deallocate (sfcn2d,a)
return
@@ -2042,8 +2389,8 @@ subroutine gsi_fv3ncdf2d_read_v1(filenamein,varname,varname2,work_sub,mype_io)
use general_commvars_mod, only: ltosi_s,ltosj_s
implicit none
- character(*) ,intent(in ) :: varname,varname2,filenamein
- real(r_kind) ,intent(out ) :: work_sub(lat2,lon2)
+ character(*) , intent(in ) :: varname,varname2,filenamein
+ real(r_kind) , intent(out ) :: work_sub(lat2,lon2)
integer(i_kind) ,intent(in ) :: mype_io
real(r_kind),allocatable,dimension(:,:,:):: uu
real(r_kind),allocatable,dimension(:):: work
@@ -2104,7 +2451,7 @@ subroutine gsi_fv3ncdf2d_read_v1(filenamein,varname,varname2,work_sub,mype_io)
return
end subroutine gsi_fv3ncdf2d_read_v1
-subroutine gsi_fv3ncdf_read(grd_ionouv,cstate_nouv,filenamein,fv3filenamegin)
+subroutine gsi_fv3ncdf_read(grd_ionouv,cstate_nouv,filenamein,fv3filenamegin,ensgrid)
!$$$ subprogram documentation block
! . . . .
! subprogram: gsi_fv3ncdf_read
@@ -2131,33 +2478,42 @@ subroutine gsi_fv3ncdf_read(grd_ionouv,cstate_nouv,filenamein,fv3filenamegin)
use kinds, only: r_kind,i_kind
- use mpimod, only: mpi_comm_world,mpi_rtype,mype
+ use mpimod, only: mpi_comm_world,mpi_rtype,mype,npe,setcomm,mpi_integer,mpi_max
use mpimod, only: MPI_INFO_NULL
use netcdf, only: nf90_open,nf90_close,nf90_get_var,nf90_noerr
- use netcdf, only: nf90_nowrite,nf90_inquire,nf90_inquire_dimension
+ use netcdf, only: nf90_nowrite,nf90_mpiio,nf90_inquire,nf90_inquire_dimension
use netcdf, only: nf90_inquire_variable
use netcdf, only: nf90_inq_varid
- use mod_fv3_lola, only: fv3_h_to_ll
+ use mod_fv3_lola, only: fv3_h_to_ll,fv3_h_to_ll_ens
use gsi_bundlemod, only: gsi_bundle
use general_sub2grid_mod, only: sub2grid_info,general_grid2sub
implicit none
- type(sub2grid_info), intent(in):: grd_ionouv
- type(gsi_bundle),intent(inout) :: cstate_nouv
- character(*),intent(in):: filenamein
- type (type_fv3regfilenameg),intent(in) ::fv3filenamegin
+ type(sub2grid_info), intent(in ) :: grd_ionouv
+ type(gsi_bundle), intent(inout) :: cstate_nouv
+ character(*), intent(in ) :: filenamein
+ type (type_fv3regfilenameg),intent(in ) ::fv3filenamegin
+ logical, intent(in ) :: ensgrid
+
real(r_kind),allocatable,dimension(:,:):: uu2d
real(r_kind),dimension(1,grd_ionouv%nlat,grd_ionouv%nlon,grd_ionouv%kbegin_loc:grd_ionouv%kend_alloc):: hwork
character(len=max_varname_length) :: varname,vgsiname
character(len=max_varname_length) :: name
- character(len=max_varname_length) :: filenamein2
-
+ character(len=max_filename_length) :: filenamein2
+ real(r_kind),allocatable,dimension(:,:):: uu2d_tmp
+ integer(i_kind) :: countloc_tmp(4),startloc_tmp(4)
- integer(i_kind) nlatcase,nloncase,nxcase,nycase,countloc(3),startloc(3)
+ integer(i_kind) nlatcase,nloncase,nxcase,nycase,countloc(4),startloc(4)
integer(i_kind) ilev,ilevtot,inative
- integer(i_kind) kbgn,kend
+ integer(i_kind) kbgn,kend,len
+ logical :: phy_smaller_domain
integer(i_kind) gfile_loc,iret,var_id
- integer(i_kind) nz,nzp1,mm1
+ integer(i_kind) nz,nzp1,mm1,nx_phy
+
+ integer(i_kind):: iworld,iworld_group,nread,mpi_comm_read,i,ierror
+ integer(i_kind),dimension(npe):: members,members_read,mype_read_rank
+ logical:: procuse
+
! for io_layout > 1
real(r_kind),allocatable,dimension(:,:):: uu2d_layout
integer(i_kind) :: nio
@@ -2167,85 +2523,155 @@ subroutine gsi_fv3ncdf_read(grd_ionouv,cstate_nouv,filenamein,fv3filenamegin)
mm1=mype+1
nloncase=grd_ionouv%nlon
nlatcase=grd_ionouv%nlat
- nxcase=nx
- nycase=ny
+ if (ensgrid) then
+ nxcase=nxens
+ nycase=nyens
+ else
+ nxcase=nx
+ nycase=ny
+ end if
kbgn=grd_ionouv%kbegin_loc
kend=grd_ionouv%kend_loc
allocate(uu2d(nxcase,nycase))
- if(fv3_io_layout_y > 1) then
- allocate(gfile_loc_layout(0:fv3_io_layout_y-1))
- do nio=0,fv3_io_layout_y-1
- write(filename_layout,'(a,a,I4.4)') trim(filenamein),'.',nio
- iret=nf90_open(filename_layout,nf90_nowrite,gfile_loc_layout(nio),comm=mpi_comm_world,info=MPI_INFO_NULL) !clt
- if(iret/=nf90_noerr) then
- write(6,*)' gsi_fv3ncdf_read: problem opening ',trim(filename_layout),gfile_loc_layout(nio),', Status = ',iret
- call flush(6)
- call stop2(333)
- endif
- enddo
- else
- iret=nf90_open(filenamein,nf90_nowrite,gfile_loc,comm=mpi_comm_world,info=MPI_INFO_NULL) !clt
- if(iret/=nf90_noerr) then
- write(6,*)' gsi_fv3ncdf_read: problem opening ',trim(filenamein),gfile_loc,', Status = ',iret
- call flush(6)
- call stop2(333)
- endif
+ procuse = .false.
+ members=-1
+ members_read=-1
+ if (kbgn<=kend) then
+ procuse = .true.
+ members(mm1) = mype
endif
- do ilevtot=kbgn,kend
- vgsiname=grd_ionouv%names(1,ilevtot)
- if(trim(vgsiname)=='delzinc') cycle !delzinc is not read from DZ ,it's started from hydrostatic height
- if(trim(vgsiname)=='amassi') cycle
- if(trim(vgsiname)=='amassj') cycle
- if(trim(vgsiname)=='amassk') cycle
- if(trim(vgsiname)=='pm2_5') cycle
- call getfv3lamfilevname(vgsiname,fv3filenamegin,filenamein2,varname)
- name=trim(varname)
- if(trim(filenamein) /= trim(filenamein2)) then
- write(6,*)'filenamein and filenamein2 are not the same as expected, stop'
- call flush(6)
- call stop2(333)
- endif
- ilev=grd_ionouv%lnames(1,ilevtot)
- nz=grd_ionouv%nsig
- nzp1=nz+1
- inative=nzp1-ilev
- startloc=(/1,1,inative/)
- countloc=(/nxcase,nycase,1/)
+ call mpi_allreduce(members,members_read,npe,mpi_integer,mpi_max,mpi_comm_world,ierror)
- if(fv3_io_layout_y > 1) then
- do nio=0,fv3_io_layout_y-1
- countloc=(/nxcase,ny_layout_len(nio),1/)
- allocate(uu2d_layout(nxcase,ny_layout_len(nio)))
- iret=nf90_inq_varid(gfile_loc_layout(nio),trim(adjustl(varname)),var_id)
- iret=nf90_get_var(gfile_loc_layout(nio),var_id,uu2d_layout,start=startloc,count=countloc)
- uu2d(:,ny_layout_b(nio):ny_layout_e(nio))=uu2d_layout
- deallocate(uu2d_layout)
- enddo
- else
- iret=nf90_inq_varid(gfile_loc,trim(adjustl(varname)),var_id)
- iret=nf90_get_var(gfile_loc,var_id,uu2d,start=startloc,count=countloc)
- endif
+ nread=0
+ mype_read_rank=-1
+ do i=1,npe
+ if (members_read(i) >= 0) then
+ nread=nread+1
+ mype_read_rank(nread) = members_read(i)
+ endif
+ enddo
+
+ call setcomm(iworld,iworld_group,nread,mype_read_rank,mpi_comm_read,ierror)
- call fv3_h_to_ll(uu2d,hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,grid_reverse_flag)
- enddo ! ilevtot
+ if (procuse) then
- if(fv3_io_layout_y > 1) then
- do nio=1,fv3_io_layout_y-1
- iret=nf90_close(gfile_loc_layout(nio))
- enddo
- deallocate(gfile_loc_layout)
- else
- iret=nf90_close(gfile_loc)
+ if(fv3_io_layout_y > 1) then
+ allocate(gfile_loc_layout(0:fv3_io_layout_y-1))
+ do nio=0,fv3_io_layout_y-1
+ write(filename_layout,'(a,a,I4.4)') trim(filenamein),'.',nio
+ iret=nf90_open(filename_layout,ior(nf90_nowrite,nf90_mpiio),gfile_loc_layout(nio),comm=mpi_comm_read,info=MPI_INFO_NULL) !clt
+ if(iret/=nf90_noerr) then
+ write(6,*)' gsi_fv3ncdf_read: problem opening ',trim(filename_layout),gfile_loc_layout(nio),', Status = ',iret
+ call stop2(333)
+ endif
+ enddo
+ else
+ iret=nf90_open(filenamein,ior(nf90_nowrite,nf90_mpiio),gfile_loc,comm=mpi_comm_read,info=MPI_INFO_NULL) !clt
+ if(iret/=nf90_noerr) then
+ write(6,*)' gsi_fv3ncdf_read: problem opening ',trim(filenamein),gfile_loc,', Status = ',iret
+ call stop2(333)
+ endif
+ endif
+ do ilevtot=kbgn,kend
+ vgsiname=grd_ionouv%names(1,ilevtot)
+ if(trim(vgsiname)=='delzinc') cycle !delzinc is not read from DZ ,it's started from hydrostatic height
+ if(trim(vgsiname)=='amassi') cycle
+ if(trim(vgsiname)=='amassj') cycle
+ if(trim(vgsiname)=='amassk') cycle
+ if(trim(vgsiname)=='pm2_5') cycle
+ call getfv3lamfilevname(vgsiname,fv3filenamegin,filenamein2,varname)
+ name=trim(varname)
+ if(trim(filenamein) /= trim(filenamein2)) then
+ write(6,*)'filenamein and filenamein2 are not the same as expected, stop'
+ call stop2(333)
+ endif
+ ilev=grd_ionouv%lnames(1,ilevtot)
+ nz=grd_ionouv%nsig
+ nzp1=nz+1
+ inative=nzp1-ilev
+ startloc=(/1,1,inative,1/)
+ countloc=(/nxcase,nycase,1,1/)
+ ! Variable ref_f3d in phy_data.nc has a smaller domain size than
+ ! dynvariables and tracers as well as a reversed order in vertical
+ if ( trim(adjustl(varname)) == 'ref_f3d' .or. trim(adjustl(varname)) == 'flash_extent_density' )then
+ iret=nf90_inquire_dimension(gfile_loc,1,name,len)
+ if(trim(name)=='xaxis_1') nx_phy=len
+ if( nx_phy == nxcase )then
+ allocate(uu2d_tmp(nxcase,nycase))
+ countloc_tmp=(/nxcase,nycase,1,1/)
+ phy_smaller_domain = .false.
+ else
+ allocate(uu2d_tmp(nxcase-6,nycase-6))
+ countloc_tmp=(/nxcase-6,nycase-6,1,1/)
+ phy_smaller_domain = .true.
+ end if
+ startloc_tmp=(/1,1,ilev,1/)
+ end if
+
+ if(fv3_io_layout_y > 1) then
+ do nio=0,fv3_io_layout_y-1
+ if (ensgrid) then
+ countloc=(/nxcase,ny_layout_lenens(nio)+1,1,1/)
+ allocate(uu2d_layout(nxcase,ny_layout_lenens(nio)+1))
+ else
+ countloc=(/nxcase,ny_layout_len(nio),1,1/)
+ allocate(uu2d_layout(nxcase,ny_layout_len(nio)))
+ end if
+ iret=nf90_inq_varid(gfile_loc_layout(nio),trim(adjustl(varname)),var_id)
+ iret=nf90_get_var(gfile_loc_layout(nio),var_id,uu2d_layout,start=startloc,count=countloc)
+ if (ensgrid) then
+ uu2d(:,ny_layout_bens(nio):ny_layout_eens(nio))=uu2d_layout
+ else
+ uu2d(:,ny_layout_b(nio):ny_layout_e(nio))=uu2d_layout
+ end if
+ deallocate(uu2d_layout)
+ enddo
+ else
+ iret=nf90_inq_varid(gfile_loc,trim(adjustl(varname)),var_id)
+ if ( trim(adjustl(varname)) == 'ref_f3d'.or. trim(adjustl(varname)) == 'flash_extent_density' )then
+ uu2d = 0.0_r_kind
+ iret=nf90_get_var(gfile_loc,var_id,uu2d_tmp,start=startloc_tmp,count=countloc_tmp)
+ where(uu2d_tmp < 0.0_r_kind)
+ uu2d_tmp = 0.0_r_kind
+ endwhere
+
+ if( phy_smaller_domain )then
+ uu2d(4:nxcase-3,4:nycase-3) = uu2d_tmp
+ else
+ uu2d(1:nxcase,1:nycase) = uu2d_tmp
+ end if
+ deallocate(uu2d_tmp)
+ else
+ iret=nf90_get_var(gfile_loc,var_id,uu2d,start=startloc,count=countloc)
+ end if
+ endif
+
+ if (ensgrid) then
+ call fv3_h_to_ll_ens(uu2d,hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,grid_reverse_flag)
+ else
+ call fv3_h_to_ll(uu2d,hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,grid_reverse_flag)
+ endif
+ enddo ! ilevtot
+
+ if(fv3_io_layout_y > 1) then
+ do nio=1,fv3_io_layout_y-1
+ iret=nf90_close(gfile_loc_layout(nio))
+ enddo
+ deallocate(gfile_loc_layout)
+ else
+ iret=nf90_close(gfile_loc)
+ endif
endif
-
+ call mpi_barrier(mpi_comm_world,ierror)
+
deallocate (uu2d)
call general_grid2sub(grd_ionouv,hwork,cstate_nouv%values)
return
-end subroutine gsi_fv3ncdf_read
+ end subroutine gsi_fv3ncdf_read
-subroutine gsi_fv3ncdf_read_v1(grd_ionouv,cstate_nouv,filenamein,fv3filenamegin)
+subroutine gsi_fv3ncdf_read_v1(grd_ionouv,cstate_nouv,filenamein,fv3filenamegin,ensgrid)
!$$$ subprogram documentation block
! . . . .
@@ -2274,47 +2700,81 @@ subroutine gsi_fv3ncdf_read_v1(grd_ionouv,cstate_nouv,filenamein,fv3filenamegin)
use kinds, only: r_kind,i_kind
- use mpimod, only: mpi_rtype,mpi_comm_world,mype,MPI_INFO_NULL
- use mpimod, only: mpi_comm_world,mpi_rtype,mype
+ use mpimod, only: npe,mpi_rtype,mpi_comm_world,mype,MPI_INFO_NULL
+ use mpimod, only: mpi_comm_world,mpi_rtype,mype,setcomm,mpi_integer,mpi_max
use netcdf, only: nf90_open,nf90_close,nf90_get_var,nf90_noerr
- use netcdf, only: nf90_nowrite,nf90_inquire,nf90_inquire_dimension
+ use netcdf, only: nf90_nowrite,nf90_mpiio,nf90_inquire,nf90_inquire_dimension
use netcdf, only: nf90_inquire_variable
use netcdf, only: nf90_inq_varid
- use mod_fv3_lola, only: fv3_h_to_ll
+ use mod_fv3_lola, only: fv3_h_to_ll,fv3_h_to_ll_ens
use gsi_bundlemod, only: gsi_bundle
use general_sub2grid_mod, only: sub2grid_info,general_grid2sub
implicit none
- type(sub2grid_info), intent(in):: grd_ionouv
- character(*),intent(in):: filenamein
- type (type_fv3regfilenameg) :: fv3filenamegin
- type(gsi_bundle),intent(inout) :: cstate_nouv
+ type(sub2grid_info), intent(in):: grd_ionouv
+ character(*), intent(in):: filenamein
+ logical, intent(in ) :: ensgrid
+ type (type_fv3regfilenameg), intent(in) :: fv3filenamegin
+ type(gsi_bundle), intent(inout) :: cstate_nouv
+
real(r_kind),allocatable,dimension(:,:):: uu2d
real(r_kind),dimension(1,grd_ionouv%nlat,grd_ionouv%nlon,grd_ionouv%kbegin_loc:grd_ionouv%kend_alloc):: hwork
- character(len=max_varname_length) :: filenamein2
+ character(len=max_filename_length) :: filenamein2
character(len=max_varname_length) :: varname,vgsiname
- integer(i_kind) nlatcase,nloncase,nxcase,nycase,countloc(3),startloc(3)
+ integer(i_kind) nlatcase,nloncase,nxcase,nycase,countloc(4),startloc(4)
integer(i_kind) kbgn,kend
integer(i_kind) var_id
integer(i_kind) inative,ilev,ilevtot
integer(i_kind) gfile_loc,iret
integer(i_kind) nzp1,mm1
+
+ integer(i_kind):: iworld,iworld_group,nread,mpi_comm_read,i,ierror
+ integer(i_kind),dimension(npe):: members,members_read,mype_read_rank
+ logical:: procuse
- mm1=mype+1
+
+
+ mm1=mype+1
nloncase=grd_ionouv%nlon
nlatcase=grd_ionouv%nlat
- nxcase=nx
- nycase=ny
+ if (ensgrid) then
+ nxcase=nxens
+ nycase=nyens
+ else
+ nxcase=nx
+ nycase=ny
+ end if
+ allocate(uu2d(nxcase,nycase))
+
kbgn=grd_ionouv%kbegin_loc
kend=grd_ionouv%kend_loc
- allocate(uu2d(nxcase,nycase))
- iret=nf90_open(filenamein,nf90_nowrite,gfile_loc,comm=mpi_comm_world,info=MPI_INFO_NULL) !clt
+ procuse = .false.
+ members=-1
+ members_read=-1
+ if (kbgn<=kend) then
+ procuse = .true.
+ members(mm1) = mype
+ endif
+ call mpi_allreduce(members,members_read,npe,mpi_integer,mpi_max,mpi_comm_world,ierror)
+
+ nread=0
+ mype_read_rank=-1
+ do i=1,npe
+ if (members_read(i) >= 0) then
+ nread=nread+1
+ mype_read_rank(nread) = members_read(i)
+ endif
+ enddo
+
+ call setcomm(iworld,iworld_group,nread,mype_read_rank,mpi_comm_read,ierror)
+
+ if (procuse) then
+ iret=nf90_open(filenamein,ior(nf90_nowrite,nf90_mpiio),gfile_loc,comm=mpi_comm_read,info=MPI_INFO_NULL) !clt
if(iret/=nf90_noerr) then
write(6,*)' gsi_fv3ncdf_read_v1: problem opening ',trim(filenamein),gfile_loc,', Status = ',iret
- call flush(6)
call stop2(333)
endif
@@ -2324,15 +2784,14 @@ subroutine gsi_fv3ncdf_read_v1(grd_ionouv,cstate_nouv,filenamein,fv3filenamegin)
call getfv3lamfilevname(vgsiname,fv3filenamegin,filenamein2,varname)
if(trim(filenamein) /= trim(filenamein2)) then
write(6,*)'filenamein and filenamein2 are not the same as expected, stop'
- call flush(6)
call stop2(333)
endif
ilev=grd_ionouv%lnames(1,ilevtot)
nz=grd_ionouv%nsig
nzp1=nz+1
inative=nzp1-ilev
- startloc=(/1,1,inative+1/)
- countloc=(/nxcase,nycase,1/)
+ startloc=(/1,1,inative+1,1/)
+ countloc=(/nxcase,nycase,1,1/)
iret=nf90_inq_varid(gfile_loc,trim(adjustl(varname)),var_id)
if(iret/=nf90_noerr) then
write(6,*)' wrong to get var_id ',var_id
@@ -2341,11 +2800,16 @@ subroutine gsi_fv3ncdf_read_v1(grd_ionouv,cstate_nouv,filenamein,fv3filenamegin)
iret=nf90_get_var(gfile_loc,var_id,uu2d,start=startloc,count=countloc)
- call fv3_h_to_ll(uu2d,hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,grid_reverse_flag)
+ if (ensgrid) then
+ call fv3_h_to_ll_ens(uu2d,hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,grid_reverse_flag)
+ else
+ call fv3_h_to_ll(uu2d,hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,grid_reverse_flag)
+ end if
enddo ! i
- call general_grid2sub(grd_ionouv,hwork,cstate_nouv%values)
iret=nf90_close(gfile_loc)
+ endif
+ call general_grid2sub(grd_ionouv,hwork,cstate_nouv%values)
deallocate (uu2d)
@@ -2353,7 +2817,7 @@ subroutine gsi_fv3ncdf_read_v1(grd_ionouv,cstate_nouv,filenamein,fv3filenamegin)
return
end subroutine gsi_fv3ncdf_read_v1
-subroutine gsi_fv3ncdf_readuv(grd_uv,ges_u,ges_v,fv3filenamegin)
+subroutine gsi_fv3ncdf_readuv(grd_uv,ges_u,ges_v,fv3filenamegin,ensgrid)
!$$$ subprogram documentation block
! . . . .
! subprogram: gsi_fv3ncdf_readuv
@@ -2375,36 +2839,42 @@ subroutine gsi_fv3ncdf_readuv(grd_uv,ges_u,ges_v,fv3filenamegin)
!
!$$$ end documentation block
use kinds, only: r_kind,i_kind
- use mpimod, only: mpi_comm_world,mpi_rtype,mype,mpi_info_null
+ use mpimod, only: mpi_comm_world,mpi_rtype,mype,mpi_info_null,npe,setcomm,mpi_integer,mpi_max
use netcdf, only: nf90_open,nf90_close,nf90_get_var,nf90_noerr
- use netcdf, only: nf90_nowrite,nf90_inquire,nf90_inquire_dimension
+ use netcdf, only: nf90_nowrite,nf90_mpiio,nf90_inquire,nf90_inquire_dimension
use netcdf, only: nf90_inquire_variable
use netcdf, only: nf90_inq_varid
- use mod_fv3_lola, only: fv3_h_to_ll,fv3uv2earth
+ use mod_fv3_lola, only: fv3_h_to_ll,fv3uv2earth,fv3_h_to_ll_ens,fv3uv2earthens
use general_sub2grid_mod, only: sub2grid_info,general_grid2sub
implicit none
- type(sub2grid_info), intent(in):: grd_uv
+ type(sub2grid_info), intent(in):: grd_uv
real(r_kind),dimension(grd_uv%lat2,grd_uv%lon2,grd_uv%nsig),intent(inout)::ges_u
real(r_kind),dimension(grd_uv%lat2,grd_uv%lon2,grd_uv%nsig),intent(inout)::ges_v
type (type_fv3regfilenameg),intent (in) :: fv3filenamegin
+ logical, intent(in ) :: ensgrid
+
real(r_kind),dimension(2,grd_uv%nlat,grd_uv%nlon,grd_uv%kbegin_loc:grd_uv%kend_alloc):: hwork
character(:), allocatable:: filenamein
real(r_kind),allocatable,dimension(:,:):: u2d,v2d
real(r_kind),allocatable,dimension(:,:):: uc2d,vc2d
- character(len=max_varname_length) :: filenamein2
+ character(len=max_filename_length) :: filenamein2
character(len=max_varname_length) :: varname,vgsiname
real(r_kind),allocatable,dimension(:,:,:,:):: worksub
integer(i_kind) u_grd_VarId,v_grd_VarId
integer(i_kind) nlatcase,nloncase
integer(i_kind) nxcase,nycase
- integer(i_kind) u_countloc(3),u_startloc(3),v_countloc(3),v_startloc(3)
+ integer(i_kind) u_countloc(4),u_startloc(4),v_countloc(4),v_startloc(4)
integer(i_kind) inative,ilev,ilevtot
integer(i_kind) kbgn,kend
integer(i_kind) gfile_loc,iret
integer(i_kind) nz,nzp1,mm1
+ integer(i_kind):: iworld,iworld_group,nread,mpi_comm_read,i,ierror
+ integer(i_kind),dimension(npe):: members,members_read,mype_read_rank
+ logical:: procuse
+
! for fv3_io_layout_y > 1
real(r_kind),allocatable,dimension(:,:):: u2d_layout,v2d_layout
integer(i_kind) :: nio
@@ -2414,8 +2884,13 @@ subroutine gsi_fv3ncdf_readuv(grd_uv,ges_u,ges_v,fv3filenamegin)
mm1=mype+1
nloncase=grd_uv%nlon
nlatcase=grd_uv%nlat
- nxcase=nx
- nycase=ny
+ if (ensgrid) then
+ nxcase=nxens
+ nycase=nyens
+ else
+ nxcase=nx
+ nycase=ny
+ end if
kbgn=grd_uv%kbegin_loc
kend=grd_uv%kend_loc
allocate(u2d(nxcase,nycase+1))
@@ -2425,109 +2900,156 @@ subroutine gsi_fv3ncdf_readuv(grd_uv,ges_u,ges_v,fv3filenamegin)
allocate (worksub(2,grd_uv%lat2,grd_uv%lon2,grd_uv%nsig))
filenamein=fv3filenamegin%dynvars
- if(fv3_io_layout_y > 1) then
- allocate(gfile_loc_layout(0:fv3_io_layout_y-1))
- do nio=0,fv3_io_layout_y-1
- write(filename_layout,'(a,a,I4.4)') trim(filenamein),".",nio
- iret=nf90_open(filename_layout,nf90_nowrite,gfile_loc_layout(nio),comm=mpi_comm_world,info=MPI_INFO_NULL)
- if(iret/=nf90_noerr) then
- write(6,*)'problem opening6 ',trim(filename_layout),gfile_loc_layout(nio),', Status = ',iret
- call flush(6)
- call stop2(333)
- endif
- enddo
- else
- iret=nf90_open(filenamein,nf90_nowrite,gfile_loc,comm=mpi_comm_world,info=MPI_INFO_NULL) !clt
- if(iret/=nf90_noerr) then
- write(6,*)' problem opening6 ',trim(filenamein),', Status = ',iret
- call flush(6)
- call stop2(333)
- endif
+ procuse = .false.
+ members=-1
+ members_read=-1
+ if (kbgn<=kend) then
+ procuse = .true.
+ members(mm1) = mype
endif
- do ilevtot=kbgn,kend
- vgsiname=grd_uv%names(1,ilevtot)
- call getfv3lamfilevname(vgsiname,fv3filenamegin,filenamein2,varname)
- if(trim(filenamein) /= trim(filenamein2)) then
- write(6,*)'filenamein and filenamein2 are not the same as expected, stop'
- call flush(6)
- call stop2(333)
- endif
- ilev=grd_uv%lnames(1,ilevtot)
- nz=grd_uv%nsig
- nzp1=nz+1
- inative=nzp1-ilev
- u_countloc=(/nxcase,nycase+1,1/)
- v_countloc=(/nxcase+1,nycase,1/)
- u_startloc=(/1,1,inative/)
- v_startloc=(/1,1,inative/)
-
- if(fv3_io_layout_y > 1) then
- do nio=0,fv3_io_layout_y-1
- u_countloc=(/nxcase,ny_layout_len(nio)+1,1/)
- allocate(u2d_layout(nxcase,ny_layout_len(nio)+1))
- call check( nf90_inq_varid(gfile_loc_layout(nio),'u',u_grd_VarId) )
- iret=nf90_get_var(gfile_loc_layout(nio),u_grd_VarId,u2d_layout,start=u_startloc,count=u_countloc)
- u2d(:,ny_layout_b(nio):ny_layout_e(nio))=u2d_layout(:,1:ny_layout_len(nio))
- if(nio==fv3_io_layout_y-1) u2d(:,ny_layout_e(nio)+1)=u2d_layout(:,ny_layout_len(nio)+1)
- deallocate(u2d_layout)
-
- v_countloc=(/nxcase+1,ny_layout_len(nio),1/)
- allocate(v2d_layout(nxcase+1,ny_layout_len(nio)))
- call check( nf90_inq_varid(gfile_loc_layout(nio),'v',v_grd_VarId) )
- iret=nf90_get_var(gfile_loc_layout(nio),v_grd_VarId,v2d_layout,start=v_startloc,count=v_countloc)
- v2d(:,ny_layout_b(nio):ny_layout_e(nio))=v2d_layout
- deallocate(v2d_layout)
- enddo
- else
- call check( nf90_inq_varid(gfile_loc,'u',u_grd_VarId) )
- iret=nf90_get_var(gfile_loc,u_grd_VarId,u2d,start=u_startloc,count=u_countloc)
- call check( nf90_inq_varid(gfile_loc,'v',v_grd_VarId) )
- iret=nf90_get_var(gfile_loc,v_grd_VarId,v2d,start=v_startloc,count=v_countloc)
- endif
- if(.not.grid_reverse_flag) then
- call reverse_grid_r_uv (u2d,nxcase,nycase+1,1)
- call reverse_grid_r_uv (v2d,nxcase+1,nycase,1)
- endif
- call fv3uv2earth(u2d(:,:),v2d(:,:),nxcase,nycase,uc2d,vc2d)
+ call mpi_allreduce(members,members_read,npe,mpi_integer,mpi_max,mpi_comm_world,ierror)
-! NOTE on transfor to earth u/v:
-! The u and v before transferring need to be in E-W/N-S grid, which is
-! defined as reversed grid here because it is revered from map view.
-!
-! Have set the following flag for grid orientation
-! grid_reverse_flag=true: E-W/N-S grid
-! grid_reverse_flag=false: W-E/S-N grid
-!
-! So for preparing the wind transferring, need to reverse the grid from
-! W-E/S-N grid to E-W/N-S grid when grid_reverse_flag=false:
-!
-! if(.not.grid_reverse_flag) call reverse_grid_r_uv
-!
-! and the last input parameter for fv3_h_to_ll is alway true:
-!
-!
- call fv3_h_to_ll(uc2d,hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,.true.)
- call fv3_h_to_ll(vc2d,hwork(2,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,.true.)
- enddo ! i
+ nread=0
+ mype_read_rank=-1
+ do i=1,npe
+ if (members_read(i) >= 0) then
+ nread=nread+1
+ mype_read_rank(nread) = members_read(i)
+ endif
+ enddo
- if(fv3_io_layout_y > 1) then
- do nio=0,fv3_io_layout_y-1
- iret=nf90_close(gfile_loc_layout(nio))
- enddo
- deallocate(gfile_loc_layout)
- else
- iret=nf90_close(gfile_loc)
+ call setcomm(iworld,iworld_group,nread,mype_read_rank,mpi_comm_read,ierror)
+
+ if (procuse) then
+ if(fv3_io_layout_y > 1) then
+ allocate(gfile_loc_layout(0:fv3_io_layout_y-1))
+ do nio=0,fv3_io_layout_y-1
+ write(filename_layout,'(a,a,I4.4)') trim(filenamein),".",nio
+ iret=nf90_open(filename_layout,nf90_nowrite,gfile_loc_layout(nio),comm=mpi_comm_read,info=MPI_INFO_NULL)
+ if(iret/=nf90_noerr) then
+ write(6,*)'problem opening6 ',trim(filename_layout),gfile_loc_layout(nio),', Status = ',iret
+ call stop2(333)
+ endif
+ enddo
+ else
+ iret=nf90_open(filenamein,ior(nf90_nowrite,nf90_mpiio),gfile_loc,comm=mpi_comm_read,info=MPI_INFO_NULL) !clt
+ if(iret/=nf90_noerr) then
+ write(6,*)' problem opening6 ',trim(filenamein),', Status = ',iret
+ call stop2(333)
+ endif
+ endif
+
+ do ilevtot=kbgn,kend
+ vgsiname=grd_uv%names(1,ilevtot)
+ call getfv3lamfilevname(vgsiname,fv3filenamegin,filenamein2,varname)
+ if(trim(filenamein) /= trim(filenamein2)) then
+ write(6,*)'filenamein and filenamein2 are not the same as expected, stop'
+ call stop2(333)
+ endif
+ ilev=grd_uv%lnames(1,ilevtot)
+ nz=grd_uv%nsig
+ nzp1=nz+1
+ inative=nzp1-ilev
+ u_countloc=(/nxcase,nycase+1,1,1/)
+ v_countloc=(/nxcase+1,nycase,1,1/)
+ u_startloc=(/1,1,inative,1/)
+ v_startloc=(/1,1,inative,1/)
+ if(fv3_io_layout_y > 1) then
+ do nio=0,fv3_io_layout_y-1
+ if (ensgrid) then
+ u_countloc=(/nxcase,ny_layout_lenens(nio)+1,1,1/)
+ allocate(u2d_layout(nxcase,ny_layout_lenens(nio)+1))
+ else
+ u_countloc=(/nxcase,ny_layout_len(nio)+1,1,1/)
+ allocate(u2d_layout(nxcase,ny_layout_len(nio)+1))
+ end if
+ call check( nf90_inq_varid(gfile_loc_layout(nio),'u',u_grd_VarId) )
+ iret=nf90_get_var(gfile_loc_layout(nio),u_grd_VarId,u2d_layout,start=u_startloc,count=u_countloc)
+ if (ensgrid) then
+ u2d(:,ny_layout_bens(nio):ny_layout_eens(nio))=u2d_layout(:,1:ny_layout_lenens(nio))
+ if(nio==fv3_io_layout_y-1) u2d(:,ny_layout_eens(nio)+1)=u2d_layout(:,ny_layout_lenens(nio)+1)
+ deallocate(u2d_layout)
+ v_countloc=(/nxcase+1,ny_layout_lenens(nio),1,1/)
+ allocate(v2d_layout(nxcase+1,ny_layout_lenens(nio)))
+ else
+ u2d(:,ny_layout_b(nio):ny_layout_e(nio))=u2d_layout(:,1:ny_layout_len(nio))
+ if(nio==fv3_io_layout_y-1) u2d(:,ny_layout_e(nio)+1)=u2d_layout(:,ny_layout_len(nio)+1)
+ deallocate(u2d_layout)
+ v_countloc=(/nxcase+1,ny_layout_len(nio),1,1/)
+ allocate(v2d_layout(nxcase+1,ny_layout_len(nio)))
+ end if
+ call check( nf90_inq_varid(gfile_loc_layout(nio),'v',v_grd_VarId) )
+ iret=nf90_get_var(gfile_loc_layout(nio),v_grd_VarId,v2d_layout,start=v_startloc,count=v_countloc)
+ if (ensgrid) then
+ v2d(:,ny_layout_bens(nio):ny_layout_eens(nio))=v2d_layout
+ else
+ v2d(:,ny_layout_b(nio):ny_layout_e(nio))=v2d_layout
+ end if
+ deallocate(v2d_layout)
+ enddo
+ else
+ call check( nf90_inq_varid(gfile_loc,'u',u_grd_VarId) )
+ iret=nf90_get_var(gfile_loc,u_grd_VarId,u2d,start=u_startloc,count=u_countloc)
+ call check( nf90_inq_varid(gfile_loc,'v',v_grd_VarId) )
+ iret=nf90_get_var(gfile_loc,v_grd_VarId,v2d,start=v_startloc,count=v_countloc)
+ endif
+
+ if(.not.grid_reverse_flag) then
+ call reverse_grid_r_uv (u2d,nxcase,nycase+1,1)
+ call reverse_grid_r_uv (v2d,nxcase+1,nycase,1)
+ endif
+ if (ensgrid) then
+ call fv3uv2earthens(u2d(:,:),v2d(:,:),nxcase,nycase,uc2d,vc2d)
+ else
+ call fv3uv2earth(u2d(:,:),v2d(:,:),nxcase,nycase,uc2d,vc2d)
+ end if
+
+ ! NOTE on transfor to earth u/v:
+ ! The u and v before transferring need to be in E-W/N-S grid, which is
+ ! defined as reversed grid here because it is revered from map view.
+ !
+ ! Have set the following flag for grid orientation
+ ! grid_reverse_flag=true: E-W/N-S grid
+ ! grid_reverse_flag=false: W-E/S-N grid
+ !
+ ! So for preparing the wind transferring, need to reverse the grid from
+ ! W-E/S-N grid to E-W/N-S grid when grid_reverse_flag=false:
+ !
+ ! if(.not.grid_reverse_flag) call reverse_grid_r_uv
+ !
+ ! and the last input parameter for fv3_h_to_ll is alway true:
+ !
+ !
+ if (ensgrid) then
+ call fv3_h_to_ll_ens(uc2d,hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,.true.)
+ call fv3_h_to_ll_ens(vc2d,hwork(2,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,.true.)
+ else
+ call fv3_h_to_ll(uc2d,hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,.true.)
+ call fv3_h_to_ll(vc2d,hwork(2,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,.true.)
+ end if
+ enddo ! i
+
+ if(fv3_io_layout_y > 1) then
+ do nio=0,fv3_io_layout_y-1
+ iret=nf90_close(gfile_loc_layout(nio))
+ enddo
+ deallocate(gfile_loc_layout)
+ else
+ iret=nf90_close(gfile_loc)
+ endif
endif
- deallocate(u2d,v2d,uc2d,vc2d)
+ call mpi_barrier(mpi_comm_world,ierror)
+ deallocate(u2d,v2d,uc2d,vc2d)
+
call general_grid2sub(grd_uv,hwork,worksub)
ges_u=worksub(1,:,:,:)
ges_v=worksub(2,:,:,:)
deallocate(worksub)
end subroutine gsi_fv3ncdf_readuv
-subroutine gsi_fv3ncdf_readuv_v1(grd_uv,ges_u,ges_v,fv3filenamegin)
+subroutine gsi_fv3ncdf_readuv_v1(grd_uv,ges_u,ges_v,fv3filenamegin,ensgrid)
!$$$ subprogram documentation block
! subprogram: gsi_fv3ncdf_readuv_v1
! prgmmr: wu w org: np22 date: 2017-11-22
@@ -2550,25 +3072,28 @@ subroutine gsi_fv3ncdf_readuv_v1(grd_uv,ges_u,ges_v,fv3filenamegin)
!$$$ end documentation block
use constants, only: half
use kinds, only: r_kind,i_kind
- use mpimod, only: mpi_comm_world,mpi_rtype,mype,mpi_info_null
+ use mpimod, only: setcomm,mpi_integer,mpi_max, npe,mpi_comm_world,mpi_rtype,mype,mpi_info_null
use netcdf, only: nf90_open,nf90_close,nf90_get_var,nf90_noerr
- use netcdf, only: nf90_nowrite,nf90_inquire,nf90_inquire_dimension
+ use netcdf, only: nf90_nowrite,nf90_mpiio,nf90_inquire,nf90_inquire_dimension
+ use netcdf, only: nf90_var_par_access,nf90_netcdf4
use netcdf, only: nf90_inquire_variable
use netcdf, only: nf90_inq_varid
- use mod_fv3_lola, only: fv3_h_to_ll,fv3uv2earth
+ use mod_fv3_lola, only: fv3_h_to_ll,fv3_h_to_ll_ens
use general_sub2grid_mod, only: sub2grid_info,general_grid2sub
implicit none
- type(sub2grid_info), intent(in):: grd_uv
- real(r_kind) ,intent(out ) :: ges_u(grd_uv%lat2,grd_uv%lon2,grd_uv%nsig)
- real(r_kind) ,intent(out ) :: ges_v(grd_uv%lat2,grd_uv%lon2,grd_uv%nsig)
+ type(sub2grid_info), intent(in):: grd_uv
+ real(r_kind) , intent(out ) :: ges_u(grd_uv%lat2,grd_uv%lon2,grd_uv%nsig)
+ real(r_kind) , intent(out ) :: ges_v(grd_uv%lat2,grd_uv%lon2,grd_uv%nsig)
type (type_fv3regfilenameg),intent (in) :: fv3filenamegin
+ logical, intent(in ) :: ensgrid
+
real(r_kind),dimension(2,grd_uv%nlat,grd_uv%nlon,grd_uv%kbegin_loc:grd_uv%kend_alloc):: hwork
character(len=:),allocatable :: filenamein
real(r_kind),allocatable,dimension(:,:):: us2d,vw2d
real(r_kind),allocatable,dimension(:,:):: uorv2d
real(r_kind),allocatable,dimension(:,:,:,:):: worksub
- character(len=max_varname_length) :: filenamein2
+ character(len=max_filename_length) :: filenamein2
character(len=max_varname_length) :: varname
integer(i_kind) nlatcase,nloncase
integer(i_kind) kbgn,kend
@@ -2580,22 +3105,52 @@ subroutine gsi_fv3ncdf_readuv_v1(grd_uv,ges_u,ges_v,fv3filenamegin)
integer(i_kind) nxcase,nycase
integer(i_kind) us_countloc(3),us_startloc(3)
integer(i_kind) vw_countloc(3),vw_startloc(3)
+ integer(i_kind):: iworld,iworld_group,nread,mpi_comm_read,i,ierror
+ integer(i_kind),dimension(npe):: members,members_read,mype_read_rank
+ logical:: procuse
allocate (worksub(2,grd_uv%lat2,grd_uv%lon2,grd_uv%nsig))
mm1=mype+1
nloncase=grd_uv%nlon
nlatcase=grd_uv%nlat
- nxcase=nx
- nycase=ny
+ if (ensgrid) then
+ nxcase=nxens
+ nycase=nyens
+ else
+ nxcase=nx
+ nycase=ny
+ end if
kbgn=grd_uv%kbegin_loc
kend=grd_uv%kend_loc
allocate (us2d(nxcase,nycase+1),vw2d(nxcase+1,nycase))
allocate (uorv2d(nxcase,nycase))
+ procuse = .false.
+ members=-1
+ members_read=-1
+ if (kbgn<=kend) then
+ procuse = .true.
+ members(mm1) = mype
+ endif
+
+ call mpi_allreduce(members,members_read,npe,mpi_integer,mpi_max,mpi_comm_world,ierror)
+
+ nread=0
+ mype_read_rank=-1
+ do i=1,npe
+ if (members_read(i) >= 0) then
+ nread=nread+1
+ mype_read_rank(nread) = members_read(i)
+ endif
+ enddo
+
+ call setcomm(iworld,iworld_group,nread,mype_read_rank,mpi_comm_read,ierror)
+
+ if (procuse) then
+
filenamein=fv3filenamegin%dynvars
- iret=nf90_open(filenamein,nf90_nowrite,gfile_loc,comm=mpi_comm_world,info=MPI_INFO_NULL) !clt
+ iret=nf90_open(filenamein,ior(nf90_netcdf4,ior(nf90_nowrite,nf90_mpiio)),gfile_loc,comm=mpi_comm_read,info=MPI_INFO_NULL) !clt
if(iret/=nf90_noerr) then
write(6,*)' gsi_fv3ncdf_read_v1: problem opening ',trim(filenamein),gfile_loc,', Status = ',iret
- call flush(6)
call stop2(333)
endif
@@ -2604,43 +3159,451 @@ subroutine gsi_fv3ncdf_readuv_v1(grd_uv,ges_u,ges_v,fv3filenamegin)
filenamein2=fv3filenamegin%dynvars
if(trim(filenamein) /= trim(filenamein2)) then
write(6,*)'filenamein and filenamein2 are not the same as expected, stop'
- call flush(6)
call stop2(333)
endif
ilev=grd_uv%lnames(1,ilevtot)
nz=grd_uv%nsig
nzp1=nz+1
inative=nzp1-ilev
- us_countloc= (/nlon_regional,nlat_regional+1,1/)
- vw_countloc= (/nlon_regional+1,nlat_regional,1/)
+ if (ensgrid) then
+ us_countloc= (/nlon_regionalens,nlat_regionalens+1,1/)
+ vw_countloc= (/nlon_regionalens+1,nlat_regionalens,1/)
+ else
+ us_countloc= (/nlon_regional,nlat_regional+1,1/)
+ vw_countloc= (/nlon_regional+1,nlat_regional,1/)
+ end if
us_startloc=(/1,1,inative+1/)
vw_startloc=(/1,1,inative+1/)
-! transfor to earth u/v, interpolate to analysis grid, reverse vertical order
- iret=nf90_inq_varid(gfile_loc,trim(adjustl("u_s")),var_id)
-
- iret=nf90_get_var(gfile_loc,var_id,us2d,start=us_startloc,count=us_countloc)
- iret=nf90_inq_varid(gfile_loc,trim(adjustl("v_w")),var_id)
- iret=nf90_get_var(gfile_loc,var_id,vw2d,start=vw_startloc,count=vw_countloc)
- do j=1,ny
- uorv2d(:,j)=half*(us2d(:,j)+us2d(:,j+1))
- enddo
-
- call fv3_h_to_ll(uorv2d(:,:),hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,grid_reverse_flag)
- do j=1,nx
- uorv2d(j,:)=half*(vw2d(j,:)+vw2d(j+1,:))
- enddo
- call fv3_h_to_ll(uorv2d(:,:),hwork(2,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,grid_reverse_flag)
-
- enddo ! iilevtoto
- call general_grid2sub(grd_uv,hwork,worksub)
- ges_u=worksub(1,:,:,:)
- ges_v=worksub(2,:,:,:)
- iret=nf90_close(gfile_loc)
- deallocate (us2d,vw2d,worksub)
+! transfor to earth u/v, interpolate to analysis grid, reverse vertical order
+ call check(nf90_inq_varid(gfile_loc,trim(adjustl("u_s")),var_id))
+
+ call check(nf90_get_var(gfile_loc,var_id,us2d,start=us_startloc,count=us_countloc))
+ iret=nf90_inq_varid(gfile_loc,trim(adjustl("v_w")),var_id)
+ iret=nf90_get_var(gfile_loc,var_id,vw2d,start=vw_startloc,count=vw_countloc)
+ do j=1,ny
+ uorv2d(:,j)=half*(us2d(:,j)+us2d(:,j+1))
+ enddo
+
+ if (ensgrid) then
+ call fv3_h_to_ll_ens(uorv2d(:,:),hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,.true.)
+ else
+ call fv3_h_to_ll(uorv2d(:,:),hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,grid_reverse_flag)
+ end if
+ do j=1,nx
+ uorv2d(j,:)=half*(vw2d(j,:)+vw2d(j+1,:))
+ enddo
+ if (ensgrid) then
+ call fv3_h_to_ll_ens(uorv2d(:,:),hwork(2,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,.true.)
+ else
+ call fv3_h_to_ll(uorv2d(:,:),hwork(2,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,grid_reverse_flag)
+ end if
+
+ enddo ! iilevtoto
+ iret=nf90_close(gfile_loc)
+ endif !procuse
+ call general_grid2sub(grd_uv,hwork,worksub)
+ ges_u=worksub(1,:,:,:)
+ ges_v=worksub(2,:,:,:)
+ deallocate (us2d,vw2d,worksub)
+
+end subroutine gsi_fv3ncdf_readuv_v1
+
+subroutine gsi_fv3ncdf_read_ens_parallel_over_ens(filenamein,fv3filenamegin, &
+ delp,tsen,w,q,oz,ql,qr,qs,qi,qg,dbz,fed,iope)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: gsi_fv3ncdf_read_ens_parallel_over_ens
+! program history log:
+! 2022-04-01 Y. Wang and X. Wang, changed from gsi_fv3ncdf_read_ens
+! for FV3LAM ensemble parallel IO in hybrid EnVar
+! poc: xuguang.wang@ou.edu
+!
+! abstract: read in fields excluding u and v
+! program history log:
+!
+! input argument list:
+! filenamein - file name to read from
+! iope - pe to read in the field
+!
+!
+! attributes:
+! language: f90
+! machine: ibm RS/6000 SP
+!
+!$$$ end documentation block
+
+
+ use kinds, only: r_kind,i_kind
+ use mpimod, only: mpi_comm_world,mpi_rtype,mype
+ use mpimod, only: MPI_INFO_NULL
+ use netcdf, only: nf90_open,nf90_close,nf90_get_var,nf90_noerr
+ use netcdf, only: nf90_nowrite,nf90_mpiio,nf90_inquire,nf90_inquire_dimension
+ use netcdf, only: nf90_inquire_variable
+ use netcdf, only: nf90_inq_varid
+ use gridmod, only: nsig,nlon,nlat
+ use mod_fv3_lola, only: fv3_h_to_ll
+ use gsi_bundlemod, only: gsi_bundle
+ use general_sub2grid_mod, only: sub2grid_info,general_grid2sub
+
+ implicit none
+ character(*), intent(in) :: filenamein
+ type (type_fv3regfilenameg), intent(in) ::fv3filenamegin
+ integer(i_kind) , intent(in) :: iope
+ real(r_kind),dimension(nlat,nlon,nsig),intent(out),optional:: delp,tsen,w,q,oz,ql,qr,qs,qi,qg,dbz,fed
+ real(r_kind),allocatable,dimension(:,:):: uu2d, uu2d_tmp
+ real(r_kind),dimension(nlat,nlon,nsig):: hwork
+ character(len=max_varname_length) :: varname
+ character(len=max_varname_length) :: name
+ character(len=max_filename_length), allocatable,dimension(:) :: varname_files
+
+ integer(i_kind) nlatcase,nloncase,nxcase,nycase,countloc(4),startloc(4),countloc_tmp(4),startloc_tmp(4)
+ integer(i_kind) ilev,ilevtot,inative,ivar
+ integer(i_kind) kbgn,kend
+ integer(i_kind) gfile_loc,iret,var_id
+ integer(i_kind) nz,nzp1,mm1,len,nx_phy
+ logical :: phy_smaller_domain
+! for io_layout > 1
+ real(r_kind),allocatable,dimension(:,:):: uu2d_layout
+ integer(i_kind) :: nio
+ integer(i_kind),allocatable :: gfile_loc_layout(:)
+ character(len=180) :: filename_layout
+
+ mm1=mype+1
+ nloncase=nlon
+ nlatcase=nlat
+ nxcase=nx
+ nycase=ny
+ kbgn=1
+ kend=nsig
+
+ if( mype == iope )then
+ allocate(uu2d(nxcase,nycase))
+ if( present(delp).or.present(tsen).or.present(w) )then ! dynvars
+ if( present(w) )then
+ allocate(varname_files(3))
+ varname_files = (/'T ','delp','W '/)
+ else
+ allocate(varname_files(2))
+ varname_files = (/'T ','delp'/)
+ end if
+ end if
+ if( present(q).or.present(ql).or.present(qr) )then ! tracers
+ if(present(qr))then
+ allocate(varname_files(7))
+ varname_files = (/'sphum ','o3mr ','liq_wat','ice_wat','rainwat','snowwat','graupel'/)
+ else
+ allocate(varname_files(2))
+ varname_files = (/'sphum',' o3mr'/)
+ end if
+ end if
+ if( present(dbz) .and. present(fed) )then ! phyvars: dbz, fed
+ allocate(varname_files(2))
+ varname_files = (/'ref_f3d ','flash_extent_density'/)
+ elseif( present(dbz) )then ! phyvars: dbz
+ allocate(varname_files(1))
+ varname_files = (/'ref_f3d'/)
+ elseif( present(fed) )then ! phyvars: fed
+ allocate(varname_files(1))
+ varname_files = (/'flash_extent_density'/)
+ end if
+
+
+ if(fv3_io_layout_y > 1) then
+ allocate(gfile_loc_layout(0:fv3_io_layout_y-1))
+ do nio=0,fv3_io_layout_y-1
+ write(filename_layout,'(a,a,I4.4)') trim(filenamein),'.',nio
+ iret=nf90_open(filename_layout,nf90_nowrite,gfile_loc_layout(nio),comm=mpi_comm_world,info=MPI_INFO_NULL)
+ if(iret/=nf90_noerr) then
+ write(6,*)' gsi_fv3ncdf_read: problem opening ',trim(filename_layout),gfile_loc_layout(nio),', Status = ',iret
+ call stop2(333)
+ endif
+ enddo
+ else
+ iret=nf90_open(filenamein,ior(nf90_nowrite,nf90_mpiio),gfile_loc)
+ if(iret/=nf90_noerr) then
+ write(6,*)' gsi_fv3ncdf_read: problem opening ',trim(filenamein),gfile_loc,', Status = ',iret
+ call stop2(333)
+ endif
+ endif
+ do ivar = 1, size(varname_files)
+ do ilevtot=kbgn,kend
+ ilev=ilevtot
+ nz=nsig
+ nzp1=nz+1
+ inative=nzp1-ilev
+ startloc=(/1,1,inative,1/)
+ countloc=(/nxcase,nycase,1,1/)
+ varname = trim(varname_files(ivar))
+ ! Variable ref_f3d in phy_data.nc has a smaller domain size than
+ ! dynvariables and tracers as well as a reversed order in vertical
+ if ( trim(adjustl(varname)) == 'ref_f3d' .or. trim(adjustl(varname)) == 'flash_extent_density' )then
+ iret=nf90_inquire_dimension(gfile_loc,1,name,len)
+ if(trim(name)=='xaxis_1') nx_phy=len
+ if( nx_phy == nxcase )then
+ allocate(uu2d_tmp(nxcase,nycase))
+ countloc_tmp=(/nxcase,nycase,1,1/)
+ phy_smaller_domain = .false.
+ else
+ allocate(uu2d_tmp(nxcase-6,nycase-6))
+ countloc_tmp=(/nxcase-6,nycase-6,1,1/)
+ phy_smaller_domain = .true.
+ end if
+ startloc_tmp=(/1,1,ilev,1/)
+ end if
+
+ if(fv3_io_layout_y > 1) then
+ do nio=0,fv3_io_layout_y-1
+ countloc=(/nxcase,ny_layout_len(nio),1,1/)
+ allocate(uu2d_layout(nxcase,ny_layout_len(nio)))
+ iret=nf90_inq_varid(gfile_loc_layout(nio),trim(adjustl(varname)),var_id)
+ iret=nf90_get_var(gfile_loc_layout(nio),var_id,uu2d_layout,start=startloc,count=countloc)
+ uu2d(:,ny_layout_b(nio):ny_layout_e(nio))=uu2d_layout
+ deallocate(uu2d_layout)
+ enddo
+ else
+ iret=nf90_inq_varid(gfile_loc,trim(adjustl(varname)),var_id)
+ if ( trim(adjustl(varname)) == 'ref_f3d' .or. trim(adjustl(varname)) == 'flash_extent_density' )then
+ uu2d = 0.0_r_kind
+ iret=nf90_get_var(gfile_loc,var_id,uu2d_tmp,start=startloc_tmp,count=countloc_tmp)
+ where(uu2d_tmp < 0.0_r_kind)
+ uu2d_tmp = 0.0_r_kind
+ endwhere
+ if(phy_smaller_domain)then
+ uu2d(4:nxcase-3,4:nycase-3) = uu2d_tmp
+ else
+ uu2d = uu2d_tmp
+ end if
+ deallocate(uu2d_tmp)
+ else
+ iret=nf90_get_var(gfile_loc,var_id,uu2d,start=startloc,count=countloc)
+ end if
+ endif
+ call fv3_h_to_ll(uu2d,hwork(:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,grid_reverse_flag)
+ enddo ! ilevtot
+ if( present(delp).or.present(tsen).or.present(w) )then ! dynvars
+ if(ivar == 1)then
+ tsen = hwork
+ else if(ivar == 2)then
+ delp = hwork
+ end if
+ if( present(w) .and. ivar == 3 )then
+ w = hwork
+ end if
+ end if
+ if( present(q).or.present(ql).or.present(qr) )then ! tracers
+ if(ivar == 1)then
+ q = hwork
+ else if(ivar == 2)then
+ oz = hwork
+ end if
+ if(present(qr))then
+ if(ivar == 3)then
+ ql = hwork
+ else if(ivar == 4)then
+ qi = hwork
+ else if(ivar == 5)then
+ qr = hwork
+ else if(ivar == 6)then
+ qs = hwork
+ else if(ivar == 7)then
+ qg = hwork
+ end if
+ end if
+ end if
+ if( present(dbz) .and. present(fed) )then ! phyvars: dbz,fed
+ if(ivar == 1) dbz = hwork
+ if(ivar == 2) fed = hwork
+ elseif( present(dbz) )then ! phyvars: dbz
+ dbz = hwork
+ elseif( present(fed) )then ! phyvars: fed
+ fed = hwork
+ end if
+
+ end do
+
+ if(fv3_io_layout_y > 1) then
+ do nio=1,fv3_io_layout_y-1
+ iret=nf90_close(gfile_loc_layout(nio))
+ enddo
+ deallocate(gfile_loc_layout)
+ else
+ iret=nf90_close(gfile_loc)
+ endif
+
+ deallocate (uu2d,varname_files)
+ end if
+
+ return
+end subroutine gsi_fv3ncdf_read_ens_parallel_over_ens
+
+subroutine gsi_fv3ncdf_readuv_ens_parallel_over_ens(ges_u,ges_v,fv3filenamegin,iope)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: gsi_fv3ncdf_readuv_ens_parallel_over_ens
+! program history log:
+! 2022-04-01 Y. Wang and X. Wang, changed from gsi_fv3ncdf_readuv_ens
+! for FV3LAM ensemble parallel IO in hybrid EnVar
+! poc: xuguang.wang@ou.edu
+!
+! abstract: read in a field from a netcdf FV3 file in mype_u,mype_v
+! then scatter the field to each PE
+! program history log:
+!
+! input argument list:
+!
+! output argument list:
+! ges_u - output sub domain u field
+! ges_v - output sub domain v field
+!
+! attributes:
+! language: f90
+! machine: ibm RS/6000 SP
+!
+!$$$ end documentation block
+ use kinds, only: r_kind,i_kind
+ use mpimod, only: mpi_comm_world,mpi_rtype,mype,mpi_info_null
+ use gridmod, only: nsig,nlon,nlat
+ use netcdf, only: nf90_open,nf90_close,nf90_get_var,nf90_noerr
+ use netcdf, only: nf90_nowrite,nf90_inquire,nf90_inquire_dimension
+ use netcdf, only: nf90_inquire_variable
+ use netcdf, only: nf90_inq_varid
+ use mod_fv3_lola, only: fv3_h_to_ll,fv3uv2earth
+ use general_sub2grid_mod, only: sub2grid_info,general_grid2sub
+
+ implicit none
+ real(r_kind) ,intent(out ) :: ges_u(nlat,nlon,nsig)
+ real(r_kind) ,intent(out ) :: ges_v(nlat,nlon,nsig)
+ type (type_fv3regfilenameg),intent (in) :: fv3filenamegin
+ integer(i_kind),intent(in) :: iope
+
+ real(r_kind),dimension(2,nlat,nlon,nsig):: hwork
+ character(:), allocatable:: filenamein
+ real(r_kind),allocatable,dimension(:,:):: u2d,v2d
+ real(r_kind),allocatable,dimension(:,:):: uc2d,vc2d
+ integer(i_kind) u_grd_VarId,v_grd_VarId
+ integer(i_kind) nlatcase,nloncase
+ integer(i_kind) nxcase,nycase
+ integer(i_kind) u_countloc(4),u_startloc(4),v_countloc(4),v_startloc(4)
+ integer(i_kind) inative,ilev,ilevtot
+ integer(i_kind) kbgn,kend
+
+ integer(i_kind) gfile_loc,iret
+ integer(i_kind) nz,nzp1,mm1
+
+! for fv3_io_layout_y > 1
+ real(r_kind),allocatable,dimension(:,:):: u2d_layout,v2d_layout
+ integer(i_kind) :: nio
+ integer(i_kind),allocatable :: gfile_loc_layout(:)
+ character(len=180) :: filename_layout
+
+ mm1=mype+1
+ nloncase=nlon
+ nlatcase=nlat
+ nxcase=nx
+ nycase=ny
+ kbgn=1
+ kend=nsig
+ if( mype == iope )then
+ allocate(u2d(nxcase,nycase+1))
+ allocate(v2d(nxcase+1,nycase))
+ allocate(uc2d(nxcase,nycase))
+ allocate(vc2d(nxcase,nycase))
+ filenamein=fv3filenamegin%dynvars
+
+ if(fv3_io_layout_y > 1) then
+ allocate(gfile_loc_layout(0:fv3_io_layout_y-1))
+ do nio=0,fv3_io_layout_y-1
+ write(filename_layout,'(a,a,I4.4)') trim(filenamein),".",nio
+ iret=nf90_open(filename_layout,nf90_nowrite,gfile_loc_layout(nio),comm=mpi_comm_world,info=MPI_INFO_NULL)
+ if(iret/=nf90_noerr) then
+ write(6,*)'problem opening ',trim(filename_layout),gfile_loc_layout(nio),', Status = ',iret
+ call stop2(333)
+ endif
+ enddo
+ else
+ iret=nf90_open(filenamein,nf90_nowrite,gfile_loc)
+ if(iret/=nf90_noerr) then
+ write(6,*)' problem opening ',trim(filenamein),', Status = ',iret
+ call stop2(333)
+ endif
+ endif
+ do ilevtot=kbgn,kend
+ ilev=ilevtot
+ nz=nsig
+ nzp1=nz+1
+ inative=nzp1-ilev
+ u_countloc=(/nxcase,nycase+1,1,1/)
+ v_countloc=(/nxcase+1,nycase,1,1/)
+ u_startloc=(/1,1,inative,1/)
+ v_startloc=(/1,1,inative,1/)
+
+ if(fv3_io_layout_y > 1) then
+ do nio=0,fv3_io_layout_y-1
+ u_countloc=(/nxcase,ny_layout_len(nio)+1,1,1/)
+ allocate(u2d_layout(nxcase,ny_layout_len(nio)+1))
+ call check( nf90_inq_varid(gfile_loc_layout(nio),'u',u_grd_VarId) )
+ iret=nf90_get_var(gfile_loc_layout(nio),u_grd_VarId,u2d_layout,start=u_startloc,count=u_countloc)
+ u2d(:,ny_layout_b(nio):ny_layout_e(nio))=u2d_layout(:,1:ny_layout_len(nio))
+ if(nio==fv3_io_layout_y-1) u2d(:,ny_layout_e(nio)+1)=u2d_layout(:,ny_layout_len(nio)+1)
+ deallocate(u2d_layout)
+
+ v_countloc=(/nxcase+1,ny_layout_len(nio),1,1/)
+ allocate(v2d_layout(nxcase+1,ny_layout_len(nio)))
+ call check( nf90_inq_varid(gfile_loc_layout(nio),'v',v_grd_VarId) )
+ iret=nf90_get_var(gfile_loc_layout(nio),v_grd_VarId,v2d_layout,start=v_startloc,count=v_countloc)
+ v2d(:,ny_layout_b(nio):ny_layout_e(nio))=v2d_layout
+ deallocate(v2d_layout)
+ enddo
+ else
+ call check( nf90_inq_varid(gfile_loc,'u',u_grd_VarId) )
+ iret=nf90_get_var(gfile_loc,u_grd_VarId,u2d,start=u_startloc,count=u_countloc)
+ call check( nf90_inq_varid(gfile_loc,'v',v_grd_VarId) )
+ iret=nf90_get_var(gfile_loc,v_grd_VarId,v2d,start=v_startloc,count=v_countloc)
+ endif
+
+ if(.not.grid_reverse_flag) then
+ call reverse_grid_r_uv (u2d,nxcase,nycase+1,1)
+ call reverse_grid_r_uv (v2d,nxcase+1,nycase,1)
+ endif
+ call fv3uv2earth(u2d(:,:),v2d(:,:),nxcase,nycase,uc2d,vc2d)
+
+ ! NOTE on transfor to earth u/v:
+ ! The u and v before transferring need to be in E-W/N-S grid, which is
+ ! defined as reversed grid here because it is revered from map view.
+ !
+ ! Have set the following flag for grid orientation
+ ! grid_reverse_flag=true: E-W/N-S grid
+ ! grid_reverse_flag=false: W-E/S-N grid
+ !
+ ! So for preparing the wind transferring, need to reverse the grid
+ ! from
+ ! W-E/S-N grid to E-W/N-S grid when grid_reverse_flag=false:
+ !
+ ! if(.not.grid_reverse_flag) call reverse_grid_r_uv
+ !
+ ! and the last input parameter for fv3_h_to_ll is alway true:
+ !
+ !
+ call fv3_h_to_ll(uc2d,hwork(1,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,.true.)
+ call fv3_h_to_ll(vc2d,hwork(2,:,:,ilevtot),nxcase,nycase,nloncase,nlatcase,.true.)
+ enddo ! ilevtot
+ if(fv3_io_layout_y > 1) then
+ do nio=0,fv3_io_layout_y-1
+ iret=nf90_close(gfile_loc_layout(nio))
+ enddo
+ deallocate(gfile_loc_layout)
+ else
+ iret=nf90_close(gfile_loc)
+ endif
+ deallocate(u2d,v2d,uc2d,vc2d)
+ ges_u = hwork(1,:,:,:)
+ ges_v = hwork(2,:,:,:)
+ end if ! mype
+
+end subroutine gsi_fv3ncdf_readuv_ens_parallel_over_ens
-end subroutine gsi_fv3ncdf_readuv_v1
subroutine wrfv3_netcdf(fv3filenamegin)
!$$$ subprogram documentation block
@@ -2653,7 +3616,10 @@ subroutine wrfv3_netcdf(fv3filenamegin)
! program history log:
! 2019-04-18 CAPS(C. Tong) - import direct reflectivity DA capabilities
! 2019-11-22 CAPS(C. Tong) - modify "add_saved" to properly output analyses
-! 2021-01-05 x.zhang/lei - add code for updating delz analysis in regional da
+! 2021-01-05 x.zhang/lei - add code for updating delz analysis in regional da
+! 2022-04-01 Y. Wang and X. Wang - add code for updating reflectivity
+! 2023-07-30 Zhao - added code for the output of the analysis of
+! significant wave height (howv)
!
! input argument list:
!
@@ -2680,6 +3646,7 @@ subroutine wrfv3_netcdf(fv3filenamegin)
use directDA_radaruse_mod, only: l_cvpnr, cvpnr_pval
use gridmod, only: eta1_ll,eta2_ll
use constants, only: one
+ use obsmod, only: if_model_dbz,if_model_fed
implicit none
@@ -2695,6 +3662,8 @@ subroutine wrfv3_netcdf(fv3filenamegin)
real(r_kind),pointer,dimension(:,:,:):: ges_q =>NULL()
real(r_kind),pointer,dimension(:,: ):: ges_t2m =>NULL()
real(r_kind),pointer,dimension(:,: ):: ges_q2m =>NULL()
+ real(r_kind),pointer,dimension(:,: ):: ges_howv =>NULL()
+ real(r_kind),pointer,dimension(:,: ):: ges_gust =>NULL()
integer(i_kind) i,k
@@ -2705,6 +3674,8 @@ subroutine wrfv3_netcdf(fv3filenamegin)
real(r_kind),pointer,dimension(:,:,:):: ges_qg =>NULL()
real(r_kind),pointer,dimension(:,:,:):: ges_qnr =>NULL()
real(r_kind),pointer,dimension(:,:,:):: ges_w =>NULL()
+ real(r_kind),pointer,dimension(:,:,:):: ges_dbz =>NULL()
+ real(r_kind),pointer,dimension(:,:,:):: ges_fed =>NULL()
real(r_kind),pointer,dimension(:,:,:):: ges_delzinc =>NULL()
real(r_kind),pointer,dimension(:,:,:):: ges_delp =>NULL()
real(r_kind),dimension(:,: ),allocatable:: ges_ps_write
@@ -2794,19 +3765,31 @@ subroutine wrfv3_netcdf(fv3filenamegin)
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'u' , ges_u ,istatus);ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'v' , ges_v ,istatus);ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'q' ,ges_q ,istatus);ier=ier+istatus
- if (l_use_dbz_directDA) then
+ if (l_use_dbz_directDA .or. if_model_dbz .or.if_model_fed) then
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'ql' ,ges_ql ,istatus);ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'qi' ,ges_qi ,istatus);ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'qr' ,ges_qr ,istatus);ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'qs' ,ges_qs ,istatus);ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'qg' ,ges_qg ,istatus);ier=ier+istatus
+ if (l_use_dbz_directDA) &
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'qnr',ges_qnr,istatus);ier=ier+istatus
call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'w' , ges_w ,istatus);ier=ier+istatus
+ if( if_model_dbz )&
+ call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'dbz' , ges_dbz ,istatus);ier=ier+istatus
+ if( if_model_fed )&
+ call GSI_BundleGetPointer ( GSI_MetGuess_Bundle(it), 'fed' , ges_fed ,istatus);ier=ier+istatus
end if
if(i_use_2mq4b > 0 .and. i_use_2mt4b > 0 ) then
call GSI_BundleGetPointer (GSI_MetGuess_Bundle(it),'q2m',ges_q2m,istatus); ier=ier+istatus
call GSI_BundleGetPointer (GSI_MetGuess_Bundle(it),'t2m',ges_t2m,istatus );ier=ier+istatus
endif
+ if ( i_howv_3dda == 1 ) then
+ call GSI_BundleGetPointer (GSI_MetGuess_Bundle(it),'howv',ges_howv,istatus); ier=ier+istatus
+ endif
+ if ( i_gust_3dda == 1 ) then
+ call GSI_BundleGetPointer (GSI_MetGuess_Bundle(it),'gust',ges_gust,istatus); ier=ier+istatus
+ endif
+ if (ier/=0) call die('wrfv3_netcdf','cannot get pointers for fv3 met-fields, ier =',ier)
if (laeroana_fv3cmaq) then
call GSI_BundleGetPointer ( GSI_ChemGuess_Bundle(it), 'aalj',ges_aalj,istatus );ier=ier+istatus
@@ -2931,6 +3914,7 @@ subroutine wrfv3_netcdf(fv3filenamegin)
call gsi_copy_bundle(GSI_MetGuess_Bundle(it),gsibundle_fv3lam_dynvar_nouv)
call gsi_copy_bundle(GSI_MetGuess_Bundle(it),gsibundle_fv3lam_tracer_nouv)
+ if( if_model_dbz .or. if_model_fed ) call gsi_copy_bundle(GSI_MetGuess_Bundle(it),gsibundle_fv3lam_phyvar_nouv)
if (laeroana_fv3cmaq) then
call gsi_copy_bundle(GSI_ChemGuess_Bundle(it),gsibundle_fv3lam_tracerchem_nouv)
end if
@@ -2979,6 +3963,11 @@ subroutine wrfv3_netcdf(fv3filenamegin)
add_saved,fv3filenamegin%dynvars,fv3filenamegin)
call gsi_fv3ncdf_write(grd_fv3lam_tracer_ionouv,gsibundle_fv3lam_tracer_nouv, &
add_saved,fv3filenamegin%tracers,fv3filenamegin)
+ if( if_model_dbz .or. if_model_fed ) then
+ call gsi_fv3ncdf_write(grd_fv3lam_phyvar_ionouv,gsibundle_fv3lam_phyvar_nouv,&
+ add_saved,fv3filenamegin%phyvars,fv3filenamegin)
+ end if
+
call gsi_fv3ncdf_writeuv(grd_fv3lam_uv,ges_u,ges_v,add_saved,fv3filenamegin)
if (laeroana_fv3cmaq) then
call gsi_fv3ncdf_write(grd_fv3lam_tracerchem_ionouv,gsibundle_fv3lam_tracerchem_nouv, &
@@ -3010,6 +3999,14 @@ subroutine wrfv3_netcdf(fv3filenamegin)
call gsi_fv3ncdf_write_sfc(fv3filenamegin,'t2m',ges_t2m,add_saved)
call gsi_fv3ncdf_write_sfc(fv3filenamegin,'q2m',ges_q2m,add_saved)
endif
+!-- output analysis of howv
+ if ( i_howv_3dda == 1 ) then
+ call gsi_fv3ncdf_write_sfc(fv3filenamegin,'howv',ges_howv,add_saved)
+ endif
+!-- output analysis of gust
+ if ( i_gust_3dda == 1 ) then
+ call gsi_fv3ncdf_write_sfc(fv3filenamegin,'gust',ges_gust,add_saved)
+ endif
if(allocated(g_prsi)) deallocate(g_prsi)
@@ -3045,44 +4042,50 @@ subroutine gsi_fv3ncdf_writeuv(grd_uv,ges_u,ges_v,add_saved,fv3filenamegin)
!
!$$$ end documentation block
- use mpimod, only: mpi_rtype,mpi_comm_world,mype,mpi_info_null
+ use mpimod, only: mpi_rtype,mpi_comm_world,mype,mpi_info_null,npe,setcomm,mpi_integer,mpi_max
use netcdf, only: nf90_nowrite,nf90_inquire,nf90_inquire_dimension
use gridmod, only: nlon_regional,nlat_regional
use mod_fv3_lola, only: fv3_ll_to_h,fv3_h_to_ll, &
fv3uv2earth,earthuv2fv3
use netcdf, only: nf90_open,nf90_close,nf90_noerr
- use netcdf, only: nf90_write,nf90_inq_varid
+ use netcdf, only: nf90_write,nf90_mpiio,nf90_inq_varid,nf90_var_par_access,nf90_collective
use netcdf, only: nf90_put_var,nf90_get_var
use general_sub2grid_mod, only: sub2grid_info,general_sub2grid
implicit none
type(sub2grid_info), intent(in):: grd_uv
- real(r_kind),dimension(2,grd_uv%nlat,grd_uv%nlon,grd_uv%kbegin_loc:grd_uv%kend_alloc):: hwork
- logical ,intent(in ) :: add_saved
+ logical, intent(in ) :: add_saved
type (type_fv3regfilenameg),intent(in) ::fv3filenamegin
real(r_kind),dimension(grd_uv%lat2,grd_uv%lon2,grd_uv%nsig),intent(inout)::ges_u
real(r_kind),dimension(grd_uv%lat2,grd_uv%lon2,grd_uv%nsig),intent(inout)::ges_v
+ real(r_kind),dimension(2,grd_uv%nlat,grd_uv%nlon,grd_uv%kbegin_loc:grd_uv%kend_alloc):: hwork
integer(i_kind) :: ugrd_VarId,gfile_loc,vgrd_VarId
integer(i_kind) i,j,mm1,k,nzp1
integer(i_kind) kbgn,kend
integer(i_kind) inative,ilev,ilevtot
integer(i_kind) nlatcase,nloncase
integer(i_kind) nxcase,nycase
- integer(i_kind) u_countloc(3),u_startloc(3),v_countloc(3),v_startloc(3)
+ integer(i_kind) u_countloc(4),u_startloc(4),v_countloc(4),v_startloc(4)
character(:),allocatable:: filenamein ,varname
real(r_kind),allocatable,dimension(:,:,:,:):: worksub
real(r_kind),allocatable,dimension(:,:):: work_au,work_av
- real(r_kind),allocatable,dimension(:,:):: work_bu,work_bv
+ real(r_kind),allocatable,dimension(:,:,:):: work_bu,work_bv
real(r_kind),allocatable,dimension(:,:):: u2d,v2d,workau2,workav2
real(r_kind),allocatable,dimension(:,:):: workbu2,workbv2
+ integer(i_kind):: iworld,iworld_group,nread,mpi_comm_read,ierror
+ integer(i_kind),dimension(npe):: members,members_read,mype_read_rank
+ logical:: procuse
+
! for fv3_io_layout_y > 1
- real(r_kind),allocatable,dimension(:,:):: u2d_layout,v2d_layout
+ real(r_kind),allocatable,dimension(:,:,:):: u2d_layout,v2d_layout
integer(i_kind) :: nio
integer(i_kind),allocatable :: gfile_loc_layout(:)
character(len=180) :: filename_layout
+ integer(i_kind):: kend_native,kbgn_native
+ integer(i_kind):: istat
mm1=mype+1
@@ -3094,8 +4097,6 @@ subroutine gsi_fv3ncdf_writeuv(grd_uv,ges_u,ges_v,add_saved,fv3filenamegin)
kend=grd_uv%kend_loc
allocate( u2d(nlon_regional,nlat_regional+1))
allocate( v2d(nlon_regional+1,nlat_regional))
- allocate( work_bu(nlon_regional,nlat_regional+1))
- allocate( work_bv(nlon_regional+1,nlat_regional))
allocate (worksub(2,grd_uv%lat2,grd_uv%lon2,grd_uv%nsig))
allocate( work_au(nlatcase,nloncase),work_av(nlatcase,nloncase))
do k=1,grd_uv%nsig
@@ -3109,116 +4110,154 @@ subroutine gsi_fv3ncdf_writeuv(grd_uv,ges_u,ges_v,add_saved,fv3filenamegin)
call general_sub2grid(grd_uv,worksub,hwork)
filenamein=fv3filenamegin%dynvars
- if(fv3_io_layout_y > 1) then
- allocate(gfile_loc_layout(0:fv3_io_layout_y-1))
- do nio=0,fv3_io_layout_y-1
- write(filename_layout,'(a,a,I4.4)') trim(filenamein),".",nio
- call check( nf90_open(filename_layout,nf90_write,gfile_loc_layout(nio),comm=mpi_comm_world,info=MPI_INFO_NULL) )
- enddo
- gfile_loc=gfile_loc_layout(0)
- else
- call check( nf90_open(filenamein,nf90_write,gfile_loc,comm=mpi_comm_world,info=MPI_INFO_NULL) )
+
+ procuse = .false.
+ members=-1
+ members_read=-1
+ if (kbgn<=kend) then
+ procuse = .true.
+ members(mm1) = mype
endif
- do ilevtot=kbgn,kend
- varname=grd_uv%names(1,ilevtot)
- ilev=grd_uv%lnames(1,ilevtot)
- nz=grd_uv%nsig
- nzp1=nz+1
- inative=nzp1-ilev
- u_countloc=(/nxcase,nycase+1,1/)
- v_countloc=(/nxcase+1,nycase,1/)
- u_startloc=(/1,1,inative/)
- v_startloc=(/1,1,inative/)
+ call mpi_allreduce(members,members_read,npe,mpi_integer,mpi_max,mpi_comm_world,ierror)
- work_au=hwork(1,:,:,ilevtot)
- work_av=hwork(2,:,:,ilevtot)
+ nread=0
+ mype_read_rank=-1
+ do i=1,npe
+ if (members_read(i) >= 0) then
+ nread=nread+1
+ mype_read_rank(nread) = members_read(i)
+ endif
+ enddo
- call check( nf90_inq_varid(gfile_loc,'u',ugrd_VarId) )
- call check( nf90_inq_varid(gfile_loc,'v',vgrd_VarId) )
+ call setcomm(iworld,iworld_group,nread,mype_read_rank,mpi_comm_read,ierror)
- if(add_saved)then
- allocate( workau2(nlatcase,nloncase),workav2(nlatcase,nloncase))
- allocate( workbu2(nlon_regional,nlat_regional+1))
- allocate( workbv2(nlon_regional+1,nlat_regional))
-!!!!!!!! readin work_b !!!!!!!!!!!!!!!!
- if(fv3_io_layout_y > 1) then
+ if (procuse) then
+ if(fv3_io_layout_y > 1) then
+ allocate(gfile_loc_layout(0:fv3_io_layout_y-1))
+ do nio=0,fv3_io_layout_y-1
+ write(filename_layout,'(a,a,I4.4)') trim(filenamein),".",nio
+ call check( nf90_open(filename_layout,ior(nf90_write, nf90_mpiio),gfile_loc_layout(nio),comm=mpi_comm_read,info=MPI_INFO_NULL) )
+ enddo
+ gfile_loc=gfile_loc_layout(0)
+ else
+ call check( nf90_open(filenamein,ior(nf90_write, nf90_mpiio),gfile_loc,comm=mpi_comm_read,info=MPI_INFO_NULL) )
+ endif
+ nz=grd_uv%nsig
+ nzp1=nz+1
+ kend_native=nzp1-grd_uv%lnames(1,kbgn)
+ kbgn_native=nzp1-grd_uv%lnames(1,kend)
+ allocate( work_bu(nlon_regional,nlat_regional+1,kbgn_native:kend_native))
+ allocate( work_bv(nlon_regional+1,nlat_regional,kbgn_native:kend_native))
+ u_startloc=(/1,1,kbgn_native,1/)
+ u_countloc=(/nxcase,nycase+1,kend_native-kbgn_native+1,1/)
+ v_startloc=(/1,1,kbgn_native,1/)
+ v_countloc=(/nxcase+1,nycase,kend_native-kbgn_native+1,1/)
+ if(fv3_io_layout_y > 1) then
do nio=0,fv3_io_layout_y-1
- allocate(u2d_layout(nxcase,ny_layout_len(nio)+1))
- u_countloc=(/nxcase,ny_layout_len(nio)+1,1/)
- call check( nf90_get_var(gfile_loc_layout(nio),ugrd_VarId,u2d_layout,start=u_startloc,count=u_countloc) )
- work_bu(:,ny_layout_b(nio):ny_layout_e(nio))=u2d_layout(:,1:ny_layout_len(nio))
- if(nio==fv3_io_layout_y-1) work_bu(:,ny_layout_e(nio)+1)=u2d_layout(:,ny_layout_len(nio)+1)
- deallocate(u2d_layout)
-
- allocate(v2d_layout(nxcase+1,ny_layout_len(nio)))
- v_countloc=(/nxcase+1,ny_layout_len(nio),1/)
- call check( nf90_get_var(gfile_loc_layout(nio),vgrd_VarId,v2d_layout,start=v_startloc,count=v_countloc) )
- work_bv(:,ny_layout_b(nio):ny_layout_e(nio))=v2d_layout
- deallocate(v2d_layout)
+ allocate(u2d_layout(nxcase,ny_layout_len(nio)+1,kend_native-kbgn_native+1))
+ u_countloc=(/nxcase,ny_layout_len(nio)+1,kend_native-kbgn_native+1,1/)
+ call check( nf90_get_var(gfile_loc_layout(nio),ugrd_VarId,u2d_layout,start=u_startloc,count=u_countloc) )
+ work_bu(:,ny_layout_b(nio):ny_layout_e(nio),:)=u2d_layout(:,1:ny_layout_len(nio),:)
+ if(nio==fv3_io_layout_y-1) work_bu(:,ny_layout_e(nio)+1,:)=u2d_layout(:,ny_layout_len(nio)+1,:)
+ deallocate(u2d_layout)
+
+ allocate(v2d_layout(nxcase+1,ny_layout_len(nio),kend_native-kbgn_native+1))
+ v_countloc=(/nxcase+1,ny_layout_len(nio),kend_native-kbgn_native+1,1/)
+ call check( nf90_get_var(gfile_loc_layout(nio),vgrd_VarId,v2d_layout,start=v_startloc,count=v_countloc) )
+ work_bv(:,ny_layout_b(nio):ny_layout_e(nio),:)=v2d_layout
+ deallocate(v2d_layout)
enddo
- else
+ else
+ call check( nf90_inq_varid(gfile_loc,'u',ugrd_VarId) )
+ call check( nf90_inq_varid(gfile_loc,'v',vgrd_VarId) )
+ call check( nf90_var_par_access(gfile_loc, ugrd_VarId, nf90_collective))
+ call check( nf90_var_par_access(gfile_loc, vgrd_VarId, nf90_collective))
call check( nf90_get_var(gfile_loc,ugrd_VarId,work_bu,start=u_startloc,count=u_countloc) )
call check( nf90_get_var(gfile_loc,vgrd_VarId,work_bv,start=v_startloc,count=v_countloc) )
- endif
- if(.not.grid_reverse_flag) then
- call reverse_grid_r_uv(work_bu,nlon_regional,nlat_regional+1,1)
- call reverse_grid_r_uv(work_bv,nlon_regional+1,nlat_regional,1)
- endif
- call fv3uv2earth(work_bu,work_bv,nlon_regional,nlat_regional,u2d,v2d)
- call fv3_h_to_ll(u2d,workau2,nlon_regional,nlat_regional,nloncase,nlatcase,.true.)
- call fv3_h_to_ll(v2d,workav2,nlon_regional,nlat_regional,nloncase,nlatcase,.true.)
+ endif
+
+
+
+ do ilevtot=kbgn,kend
+ varname=grd_uv%names(1,ilevtot)
+ ilev=grd_uv%lnames(1,ilevtot)
+ inative=nzp1-ilev
+
+ work_au=hwork(1,:,:,ilevtot)
+ work_av=hwork(2,:,:,ilevtot)
+
+
+ if(add_saved)then
+ allocate( workau2(nlatcase,nloncase),workav2(nlatcase,nloncase))
+ allocate( workbu2(nlon_regional,nlat_regional+1))
+ allocate( workbv2(nlon_regional+1,nlat_regional))
+!!!!!!!! readin work_b !!!!!!!!!!!!!!!!
+
+!clt for fv3_io_layout<=1 now the nf90_get_var has been moved outside of this do loop
+!to avoid failure on hercules when L_MPI_EXTRA_FILESYSTEM=1
+ if(.not.grid_reverse_flag) then
+ call reverse_grid_r_uv(work_bu(:,:,inative),nlon_regional,nlat_regional+1,1)
+ call reverse_grid_r_uv(work_bv(:,:,inative),nlon_regional+1,nlat_regional,1)
+ endif
+ call fv3uv2earth(work_bu(:,:,inative),work_bv(:,:,inative),nlon_regional,nlat_regional,u2d,v2d)
+ call fv3_h_to_ll(u2d,workau2,nlon_regional,nlat_regional,nloncase,nlatcase,.true.)
+ call fv3_h_to_ll(v2d,workav2,nlon_regional,nlat_regional,nloncase,nlatcase,.true.)
!!!!!!!! find analysis_inc: work_a !!!!!!!!!!!!!!!!
- work_au(:,:)=work_au(:,:)-workau2(:,:)
- work_av(:,:)=work_av(:,:)-workav2(:,:)
- call fv3_ll_to_h(work_au(:,:),u2d,nloncase,nlatcase,nlon_regional,nlat_regional,.true.)
- call fv3_ll_to_h(work_av(:,:),v2d,nloncase,nlatcase,nlon_regional,nlat_regional,.true.)
- call earthuv2fv3(u2d,v2d,nlon_regional,nlat_regional,workbu2,workbv2)
+ work_au(:,:)=work_au(:,:)-workau2(:,:)
+ work_av(:,:)=work_av(:,:)-workav2(:,:)
+ call fv3_ll_to_h(work_au(:,:),u2d,nloncase,nlatcase,nlon_regional,nlat_regional,.true.)
+ call fv3_ll_to_h(work_av(:,:),v2d,nloncase,nlatcase,nlon_regional,nlat_regional,.true.)
+ call earthuv2fv3(u2d,v2d,nlon_regional,nlat_regional,workbu2,workbv2)
!!!!!!!! add analysis_inc to readin work_b !!!!!!!!!!!!!!!!
- work_bu(:,:)=work_bu(:,:)+workbu2(:,:)
- work_bv(:,:)=work_bv(:,:)+workbv2(:,:)
- deallocate(workau2,workbu2,workav2,workbv2)
- else
- call fv3_ll_to_h(work_au(:,:),u2d,nloncase,nlatcase,nlon_regional,nlat_regional,.true.)
- call fv3_ll_to_h(work_av(:,:),v2d,nloncase,nlatcase,nlon_regional,nlat_regional,.true.)
- call earthuv2fv3(u2d,v2d,nlon_regional,nlat_regional,work_bu(:,:),work_bv(:,:))
- endif
- if(.not.grid_reverse_flag) then
- call reverse_grid_r_uv(work_bu,nlon_regional,nlat_regional+1,1)
- call reverse_grid_r_uv(work_bv,nlon_regional+1,nlat_regional,1)
- endif
-
- if(fv3_io_layout_y > 1) then
- do nio=0,fv3_io_layout_y-1
- allocate(u2d_layout(nxcase,ny_layout_len(nio)+1))
- u_countloc=(/nxcase,ny_layout_len(nio)+1,1/)
- u2d_layout=work_bu(:,ny_layout_b(nio):ny_layout_e(nio)+1)
- call check( nf90_put_var(gfile_loc_layout(nio),ugrd_VarId,u2d_layout,start=u_startloc,count=u_countloc) )
- deallocate(u2d_layout)
-
- allocate(v2d_layout(nxcase+1,ny_layout_len(nio)))
- v_countloc=(/nxcase+1,ny_layout_len(nio),1/)
- v2d_layout=work_bv(:,ny_layout_b(nio):ny_layout_e(nio))
- call check( nf90_put_var(gfile_loc_layout(nio),vgrd_VarId,v2d_layout,start=v_startloc,count=v_countloc) )
- deallocate(v2d_layout)
- enddo
- else
- call check( nf90_put_var(gfile_loc,ugrd_VarId,work_bu,start=u_startloc,count=u_countloc) )
- call check( nf90_put_var(gfile_loc,vgrd_VarId,work_bv,start=v_startloc,count=v_countloc) )
- endif
- enddo !ilevltot
+ work_bu(:,:,inative)=work_bu(:,:,inative)+workbu2(:,:)
+ work_bv(:,:,inative)=work_bv(:,:,inative)+workbv2(:,:)
+ deallocate(workau2,workbu2,workav2,workbv2)
+ else
+ call fv3_ll_to_h(work_au(:,:),u2d,nloncase,nlatcase,nlon_regional,nlat_regional,.true.)
+ call fv3_ll_to_h(work_av(:,:),v2d,nloncase,nlatcase,nlon_regional,nlat_regional,.true.)
+ call earthuv2fv3(u2d,v2d,nlon_regional,nlat_regional,work_bu(:,:,inative),work_bv(:,:,inative))
+ endif
+ if(.not.grid_reverse_flag) then
+ call reverse_grid_r_uv(work_bu(:,:,inative),nlon_regional,nlat_regional+1,1)
+ call reverse_grid_r_uv(work_bv(:,:,inative),nlon_regional+1,nlat_regional,1)
+ endif
+ enddo !ilevltot
+
+ if(fv3_io_layout_y > 1) then
+ do nio=0,fv3_io_layout_y-1
+ allocate(u2d_layout(nxcase,ny_layout_len(nio)+1,kend_native-kbgn_native+1))
+ u_countloc=(/nxcase,ny_layout_len(nio)+1,kend_native-kbgn_native+1,1/)
+ u2d_layout=work_bu(:,ny_layout_b(nio):ny_layout_e(nio)+1,:)
+ call check( nf90_put_var(gfile_loc_layout(nio),ugrd_VarId,u2d_layout,start=u_startloc,count=u_countloc) )
+ deallocate(u2d_layout)
+
+ allocate(v2d_layout(nxcase+1,ny_layout_len(nio),kend_native-kbgn_native+1))
+ v_countloc=(/nxcase+1,ny_layout_len(nio),kend_native-kbgn_native+1,1/)
+ v2d_layout=work_bv(:,ny_layout_b(nio):ny_layout_e(nio),:)
+ call check( nf90_put_var(gfile_loc_layout(nio),vgrd_VarId,v2d_layout,start=v_startloc,count=v_countloc) )
+ deallocate(v2d_layout)
+ enddo
+ else
+ call check( nf90_put_var(gfile_loc,ugrd_VarId,work_bu,start=u_startloc,count=u_countloc) )
+ call check( nf90_put_var(gfile_loc,vgrd_VarId,work_bv,start=v_startloc,count=v_countloc) )
+ endif
- if(fv3_io_layout_y > 1) then
- do nio=0,fv3_io_layout_y-1
- call check( nf90_close(gfile_loc_layout(nio)) )
- enddo
- deallocate(gfile_loc_layout)
- else
- call check( nf90_close(gfile_loc) )
+ if(fv3_io_layout_y > 1) then
+ do nio=0,fv3_io_layout_y-1
+ call check( nf90_close(gfile_loc_layout(nio)) )
+ enddo
+ deallocate(gfile_loc_layout)
+ else
+ call check( nf90_close(gfile_loc) )
+ endif
+ deallocate(work_bu,work_bv)
endif
- deallocate(work_bu,work_bv,u2d,v2d)
- deallocate(work_au,work_av)
+ call mpi_barrier(mpi_comm_world,ierror)
+
+ deallocate(u2d,v2d)
+ deallocate(work_au,work_av)
end subroutine gsi_fv3ncdf_writeuv
subroutine gsi_fv3ncdf_writeuv_v1(grd_uv,ges_u,ges_v,add_saved,fv3filenamegin)
@@ -3249,20 +4288,21 @@ subroutine gsi_fv3ncdf_writeuv_v1(grd_uv,ges_u,ges_v,add_saved,fv3filenamegin)
!$$$ end documentation block
use constants, only: half,zero
- use mpimod, only: mpi_rtype,mpi_comm_world,mype,mpi_info_null
+ use mpimod, only: npe, setcomm,mpi_integer,mpi_max,mpi_rtype,mpi_comm_world,mype,mpi_info_null
use gridmod, only: nlon_regional,nlat_regional
use mod_fv3_lola, only: fv3_ll_to_h,fv3_h_to_ll, &
fv3uv2earth,earthuv2fv3
use netcdf, only: nf90_open,nf90_close,nf90_noerr
- use netcdf, only: nf90_write,nf90_inq_varid
+ use netcdf, only: nf90_write, nf90_mpiio,nf90_inq_varid,nf90_var_par_access,nf90_collective
use netcdf, only: nf90_put_var,nf90_get_var
use general_sub2grid_mod, only: sub2grid_info,general_sub2grid
implicit none
- type(sub2grid_info), intent(in):: grd_uv
+ type(sub2grid_info), intent(in) :: grd_uv
real(r_kind),dimension(grd_uv%lat2,grd_uv%lon2,grd_uv%nsig),intent(inout)::ges_u
real(r_kind),dimension(grd_uv%lat2,grd_uv%lon2,grd_uv%nsig),intent(inout)::ges_v
- logical ,intent(in ) :: add_saved
- type (type_fv3regfilenameg),intent (in) :: fv3filenamegin
+ logical, intent(in) :: add_saved
+ type (type_fv3regfilenameg),intent(in) :: fv3filenamegin
+
real(r_kind),dimension(2,grd_uv%nlat,grd_uv%nlon,grd_uv%kbegin_loc:grd_uv%kend_alloc):: hwork
character(len=:),allocatable :: filenamein
character(len=max_varname_length) :: varname
@@ -3275,14 +4315,20 @@ subroutine gsi_fv3ncdf_writeuv_v1(grd_uv,ges_u,ges_v,add_saved,fv3filenamegin)
integer(i_kind) inative,ilev,ilevtot
real(r_kind),allocatable,dimension(:,:,:,:):: worksub
real(r_kind),allocatable,dimension(:,:):: work_au,work_av
- real(r_kind),allocatable,dimension(:,:):: work_bu_s,work_bv_s
- real(r_kind),allocatable,dimension(:,:):: work_bu_w,work_bv_w
+ real(r_kind),allocatable,dimension(:,:,:):: work_bu_s,work_bv_s
+ real(r_kind),allocatable,dimension(:,:,:):: work_bu_w,work_bv_w
real(r_kind),allocatable,dimension(:,:):: u2d,v2d,workau2,workav2
real(r_kind),allocatable,dimension(:,:):: workbu_s2,workbv_s2
real(r_kind),allocatable,dimension(:,:):: workbu_w2,workbv_w2
integer(i_kind) nlatcase,nloncase,nxcase,nycase
- integer(i_kind) uw_countloc(3),us_countloc(3),uw_startloc(3),us_startloc(3)
- integer(i_kind) vw_countloc(3),vs_countloc(3),vw_startloc(3),vs_startloc(3)
+ integer(i_kind) uw_countloc(4),us_countloc(4),uw_startloc(4),us_startloc(4)
+ integer(i_kind) vw_countloc(4),vs_countloc(4),vw_startloc(4),vs_startloc(4)
+ integer(i_kind):: kend_native,kbgn_native,kdim_native
+
+
+ integer(i_kind):: iworld,iworld_group,nread,mpi_comm_read,ierror
+ integer(i_kind),dimension(npe):: members,members_read,mype_read_rank
+ logical:: procuse
mm1=mype+1
nloncase=grd_uv%nlon
@@ -3304,61 +4350,96 @@ subroutine gsi_fv3ncdf_writeuv_v1(grd_uv,ges_u,ges_v,add_saved,fv3filenamegin)
allocate( u2d(nlon_regional,nlat_regional))
allocate( v2d(nlon_regional,nlat_regional))
- allocate( work_bu_s(nlon_regional,nlat_regional+1))
- allocate( work_bv_s(nlon_regional,nlat_regional+1))
- allocate( work_bu_w(nlon_regional+1,nlat_regional))
- allocate( work_bv_w(nlon_regional+1,nlat_regional))
allocate( work_au(nlatcase,nloncase),work_av(nlatcase,nloncase))
+
if(add_saved) allocate( workau2(nlatcase,nloncase),workav2(nlatcase,nloncase))
- allocate( workbu_w2(nlon_regional+1,nlat_regional))
- allocate( workbv_w2(nlon_regional+1,nlat_regional))
- allocate( workbu_s2(nlon_regional,nlat_regional+1))
- allocate( workbv_s2(nlon_regional,nlat_regional+1))
+ allocate( workbu_w2(nlon_regional+1,nlat_regional))
+ allocate( workbv_w2(nlon_regional+1,nlat_regional))
+ allocate( workbu_s2(nlon_regional,nlat_regional+1))
+ allocate( workbv_s2(nlon_regional,nlat_regional+1))
filenamein=fv3filenamegin%dynvars
- call check( nf90_open(filenamein,nf90_write,gfile_loc,comm=mpi_comm_world,info=MPI_INFO_NULL) )
- do ilevtot=kbgn,kend
- varname=grd_uv%names(1,ilevtot)
- ilev=grd_uv%lnames(1,ilevtot)
- nz=grd_uv%nsig
- nzp1=nz+1
- inative=nzp1-ilev
+
+
+ procuse = .false.
+ members=-1
+ members_read=-1
+ if (kbgn<=kend) then
+ procuse = .true.
+ members(mm1) = mype
+ endif
+
+ call mpi_allreduce(members,members_read,npe,mpi_integer,mpi_max,mpi_comm_world,ierror)
+
+ nread=0
+ mype_read_rank=-1
+ do i=1,npe
+ if (members_read(i) >= 0) then
+ nread=nread+1
+ mype_read_rank(nread) = members_read(i)
+ endif
+ enddo
+
+ call setcomm(iworld,iworld_group,nread,mype_read_rank,mpi_comm_read,ierror)
+
+ if (procuse) then
+
- uw_countloc= (/nlon_regional+1,nlat_regional,1/)
- us_countloc= (/nlon_regional,nlat_regional+1,1/)
- vw_countloc= (/nlon_regional+1,nlat_regional,1/)
- vs_countloc= (/nlon_regional,nlat_regional+1,1/)
+ call check( nf90_open(filenamein,ior(nf90_write, nf90_mpiio),gfile_loc,comm=mpi_comm_read,info=MPI_INFO_NULL) )
+
+ call check( nf90_inq_varid(gfile_loc,'u_s',u_sgrd_VarId) )
+ call check( nf90_var_par_access(gfile_loc, u_sgrd_VarId, nf90_collective))
+ call check( nf90_inq_varid(gfile_loc,'u_w',u_wgrd_VarId) )
+ call check( nf90_var_par_access(gfile_loc, u_wgrd_VarId, nf90_collective))
+ call check( nf90_inq_varid(gfile_loc,'v_s',v_sgrd_VarId) )
+ call check( nf90_var_par_access(gfile_loc, v_sgrd_VarId, nf90_collective))
+ call check( nf90_inq_varid(gfile_loc,'v_w',v_wgrd_VarId) )
+ call check( nf90_var_par_access(gfile_loc, v_wgrd_VarId, nf90_collective))
+ nz=grd_uv%nsig
+ nzp1=nz+1
+ kend_native=nzp1-grd_uv%lnames(1,kbgn)
+ kbgn_native=nzp1-grd_uv%lnames(1,kend)
+ kdim_native=kend_native-kbgn_native+1
+
+ uw_countloc= (/nlon_regional+1,nlat_regional,kdim_native,1/)
+ us_countloc= (/nlon_regional,nlat_regional+1,kdim_native,1/)
+ vw_countloc= (/nlon_regional+1,nlat_regional,kdim_native,1/)
+ vs_countloc= (/nlon_regional,nlat_regional+1,kdim_native,1/)
- uw_startloc=(/1,1,inative+1/)
- us_startloc=(/1,1,inative+1/)
- vw_startloc=(/1,1,inative+1/)
- vs_startloc=(/1,1,inative+1/)
+ uw_startloc=(/1,1,kbgn_native+1,1/) !In the coldstart files, there is an extra top level
+ us_startloc=(/1,1,kbgn_native+1,1/)
+ vw_startloc=(/1,1,kbgn_native+1,1/)
+ vs_startloc=(/1,1,kbgn_native+1,1/)
+ allocate( work_bu_s(nlon_regional,nlat_regional+1,kbgn_native:kend_native))
+ allocate( work_bv_s(nlon_regional,nlat_regional+1,kbgn_native:kend_native))
+ allocate( work_bu_w(nlon_regional+1,nlat_regional,kbgn_native:kend_native))
+ allocate( work_bv_w(nlon_regional+1,nlat_regional,kbgn_native:kend_native))
+!!!!!!!! readin work_b !!!!!!!!!!!!!!!!
+ call check( nf90_get_var(gfile_loc,u_sgrd_VarId,work_bu_s,start=us_startloc,count=us_countloc) )
+ call check( nf90_get_var(gfile_loc,u_wgrd_VarId,work_bu_w,start=uw_startloc,count=uw_countloc) )
+ call check( nf90_get_var(gfile_loc,v_sgrd_VarId,work_bv_s,start=vs_startloc,count=vs_countloc) )
+ call check( nf90_get_var(gfile_loc,v_wgrd_VarId,work_bv_w,start=vw_startloc,count=vw_countloc) )
+ do ilevtot=kbgn,kend
+ varname=grd_uv%names(1,ilevtot)
+ ilev=grd_uv%lnames(1,ilevtot)
+ inative=nzp1-ilev
work_au=hwork(1,:,:,ilevtot)
work_av=hwork(2,:,:,ilevtot)
- call check( nf90_inq_varid(gfile_loc,'u_s',u_sgrd_VarId) )
- call check( nf90_inq_varid(gfile_loc,'u_w',u_wgrd_VarId) )
- call check( nf90_inq_varid(gfile_loc,'v_s',v_sgrd_VarId) )
- call check( nf90_inq_varid(gfile_loc,'v_w',v_wgrd_VarId) )
-!!!!!!!! readin work_b !!!!!!!!!!!!!!!!
- call check( nf90_get_var(gfile_loc,u_sgrd_VarId,work_bu_s,start=us_startloc,count=us_countloc) )
- call check( nf90_get_var(gfile_loc,u_wgrd_VarId,work_bu_w,start=uw_startloc,count=uw_countloc) )
- call check( nf90_get_var(gfile_loc,v_sgrd_VarId,work_bv_s,start=vs_startloc,count=vs_countloc) )
- call check( nf90_get_var(gfile_loc,v_wgrd_VarId,work_bv_w,start=vw_startloc,count=vw_countloc) )
if(add_saved)then
do j=1,nlat_regional
- u2d(:,j)=half * (work_bu_s(:,j)+ work_bu_s(:,j+1))
+ u2d(:,j)=half * (work_bu_s(:,j,inative)+ work_bu_s(:,j+1,inative))
enddo
do i=1,nlon_regional
- v2d(i,:)=half*(work_bv_w(i,:)+work_bv_w(i+1,:))
+ v2d(i,:)=half*(work_bv_w(i,:,inative)+work_bv_w(i+1,:,inative))
enddo
call fv3_h_to_ll(u2d,workau2,nlon_regional,nlat_regional,nloncase,nlatcase,grid_reverse_flag)
call fv3_h_to_ll(v2d,workav2,nlon_regional,nlat_regional,nloncase,nlatcase,grid_reverse_flag)
@@ -3388,44 +4469,46 @@ subroutine gsi_fv3ncdf_writeuv_v1(grd_uv,ges_u,ges_v,add_saved,fv3filenamegin)
- work_bu_w(:,:)=work_bu_w(:,:)+workbu_w2(:,:)
- work_bu_s(:,:)=work_bu_s(:,:)+workbu_s2(:,:)
- work_bv_w(:,:)=work_bv_w(:,:)+workbv_w2(:,:)
- work_bv_s(:,:)=work_bv_s(:,:)+workbv_s2(:,:)
+ work_bu_w(:,:,inative)=work_bu_w(:,:,inative)+workbu_w2(:,:)
+ work_bu_s(:,:,inative)=work_bu_s(:,:,inative)+workbu_s2(:,:)
+ work_bv_w(:,:,inative)=work_bv_w(:,:,inative)+workbv_w2(:,:)
+ work_bv_s(:,:,inative)=work_bv_s(:,:,inative)+workbv_s2(:,:)
else
call fv3_ll_to_h(work_au(:,:),u2d,nloncase,nlatcase,nlon_regional,nlat_regional,grid_reverse_flag)
call fv3_ll_to_h(work_av(:,:),v2d,nloncase,nlatcase,nlon_regional,nlat_regional,grid_reverse_flag)
do i=2,nlon_regional
- work_bu_w(i,:)=half*(u2d(i-1,:)+u2d(i,:))
- work_bv_w(i,:)=half*(v2d(i-1,:)+v2d(i,:))
+ work_bu_w(i,:,inative)=half*(u2d(i-1,:)+u2d(i,:))
+ work_bv_w(i,:,inative)=half*(v2d(i-1,:)+v2d(i,:))
enddo
- work_bu_w(1,:)=u2d(1,:)
- work_bv_w(1,:)=v2d(1,:)
- work_bu_w(nlon_regional+1,:)=u2d(nlon_regional,:)
- work_bv_w(nlon_regional+1,:)=v2d(nlon_regional,:)
+ work_bu_w(1,:,inative)=u2d(1,:)
+ work_bv_w(1,:,inative)=v2d(1,:)
+ work_bu_w(nlon_regional+1,:,inative)=u2d(nlon_regional,:)
+ work_bv_w(nlon_regional+1,:,inative)=v2d(nlon_regional,:)
do j=2,nlat_regional
- work_bu_s(:,j)=half*(u2d(:,j-1)+u2d(:,j))
- work_bv_s(:,j)=half*(v2d(:,j-1)+v2d(:,j))
+ work_bu_s(:,j,inative)=half*(u2d(:,j-1)+u2d(:,j))
+ work_bv_s(:,j,inative)=half*(v2d(:,j-1)+v2d(:,j))
enddo
- work_bu_s(:,1)=u2d(:,1)
- work_bv_s(:,1)=v2d(:,1)
- work_bu_s(:,nlat_regional+1)=u2d(:,nlat_regional)
- work_bv_s(:,nlat_regional+1)=v2d(:,nlat_regional)
+ work_bu_s(:,1,inative)=u2d(:,1)
+ work_bv_s(:,1,inative)=v2d(:,1)
+ work_bu_s(:,nlat_regional+1,inative)=u2d(:,nlat_regional)
+ work_bv_s(:,nlat_regional+1,inative)=v2d(:,nlat_regional)
endif
-
- call check( nf90_put_var(gfile_loc,u_wgrd_VarId,work_bu_w,start=uw_startloc,count=uw_countloc) )
- call check( nf90_put_var(gfile_loc,u_sgrd_VarId,work_bu_s,start=us_startloc,count=us_countloc) )
- call check( nf90_put_var(gfile_loc,v_wgrd_VarId,work_bv_w,start=vw_startloc,count=vw_countloc) )
- call check( nf90_put_var(gfile_loc,v_sgrd_VarId,work_bv_s,start=vs_startloc,count=vs_countloc) )
enddo !
+
+ call check( nf90_put_var(gfile_loc,u_wgrd_VarId,work_bu_w,start=uw_startloc,count=uw_countloc) )
+ call check( nf90_put_var(gfile_loc,u_sgrd_VarId,work_bu_s,start=us_startloc,count=us_countloc) )
+ call check( nf90_put_var(gfile_loc,v_wgrd_VarId,work_bv_w,start=vw_startloc,count=vw_countloc) )
+ call check( nf90_put_var(gfile_loc,v_sgrd_VarId,work_bv_s,start=vs_startloc,count=vs_countloc) )
call check( nf90_close(gfile_loc) )
deallocate(work_bu_w,work_bv_w)
deallocate(work_bu_s,work_bv_s)
+ endif !procuse
+
deallocate(work_au,work_av,u2d,v2d)
if(add_saved) deallocate(workau2,workav2)
if (allocated(workbu_w2)) then
@@ -3592,34 +4675,43 @@ subroutine gsi_fv3ncdf_write(grd_ionouv,cstate_nouv,add_saved,filenamein,fv3file
!
!$$$ end documentation block
- use mpimod, only: mpi_rtype,mpi_comm_world,mype,mpi_info_null
+ use mpimod, only: mpi_rtype,mpi_comm_world,mype,mpi_info_null,npe,setcomm,mpi_integer,mpi_max
use mod_fv3_lola, only: fv3_ll_to_h
use mod_fv3_lola, only: fv3_h_to_ll
use netcdf, only: nf90_open,nf90_close
- use netcdf, only: nf90_write,nf90_inq_varid
- use netcdf, only: nf90_put_var,nf90_get_var
+ use netcdf, only: nf90_write,nf90_netcdf4, nf90_mpiio,nf90_inq_varid
+ use netcdf, only: nf90_put_var,nf90_get_var,nf90_independent,nf90_var_par_access
+ use netcdf, only: nf90_inquire_dimension
use gsi_bundlemod, only: gsi_bundle
use general_sub2grid_mod, only: sub2grid_info,general_sub2grid
implicit none
- type(sub2grid_info), intent(in):: grd_ionouv
- type(gsi_bundle),intent(inout) :: cstate_nouv
- logical ,intent(in ) :: add_saved
- character(len=:), allocatable, intent(in) :: filenamein
- type (type_fv3regfilenameg),intent (in) :: fv3filenamegin
+ type(sub2grid_info), intent(in) :: grd_ionouv
+ type(gsi_bundle), intent(inout):: cstate_nouv
+ logical, intent(in ):: add_saved
+ character(len=:), allocatable, intent(in) :: filenamein
+ type (type_fv3regfilenameg), intent(in) :: fv3filenamegin
+
real(r_kind),dimension(1,grd_ionouv%nlat,grd_ionouv%nlon,grd_ionouv%kbegin_loc:grd_ionouv%kend_alloc):: hwork
- character(len=max_varname_length) :: filenamein2
- character(len=max_varname_length) :: varname,vgsiname
+ character(len=max_filename_length) :: filenamein2
+ character(len=max_varname_length) :: varname,vgsiname,name
- integer(i_kind) nlatcase,nloncase,nxcase,nycase,countloc(3),startloc(3)
+ integer(i_kind) nlatcase,nloncase,nxcase,nycase,countloc(4),startloc(4)
+ integer(i_kind) countloc_tmp(4),startloc_tmp(4)
integer(i_kind) kbgn,kend
integer(i_kind) inative,ilev,ilevtot
integer(i_kind) :: VarId,gfile_loc
- integer(i_kind) mm1,nzp1
+ integer(i_kind) mm1,nzp1,len,nx_phy,iret
+ logical :: phy_smaller_domain
real(r_kind),allocatable,dimension(:,:):: work_a
real(r_kind),allocatable,dimension(:,:):: work_b
real(r_kind),allocatable,dimension(:,:):: workb2,worka2
+ real(r_kind),allocatable,dimension(:,:):: work_b_tmp
+ integer(i_kind):: iworld,iworld_group,nread,mpi_comm_read,i,ierror
+ integer(i_kind),dimension(npe):: members,members_read,mype_read_rank
+ logical:: procuse
+
! for io_layout > 1
real(r_kind),allocatable,dimension(:,:):: work_b_layout
integer(i_kind) :: nio
@@ -3641,104 +4733,171 @@ subroutine gsi_fv3ncdf_write(grd_ionouv,cstate_nouv,add_saved,filenamein,fv3file
allocate( workb2(nlon_regional,nlat_regional))
allocate( worka2(nlatcase,nloncase))
- if(fv3_io_layout_y > 1) then
- allocate(gfile_loc_layout(0:fv3_io_layout_y-1))
- do nio=0,fv3_io_layout_y-1
- write(filename_layout,'(a,a,I4.4)') trim(filenamein),'.',nio
- call check( nf90_open(filename_layout,nf90_write,gfile_loc_layout(nio),comm=mpi_comm_world,info=MPI_INFO_NULL) )
- enddo
- gfile_loc=gfile_loc_layout(0)
- else
- call check( nf90_open(filenamein,nf90_write,gfile_loc,comm=mpi_comm_world,info=MPI_INFO_NULL) )
+ procuse = .false.
+ members=-1
+ members_read=-1
+ if (kbgn<=kend) then
+ procuse = .true.
+ members(mm1) = mype
endif
- do ilevtot=kbgn,kend
- vgsiname=grd_ionouv%names(1,ilevtot)
- if(trim(vgsiname)=='amassi') cycle
- if(trim(vgsiname)=='amassj') cycle
- if(trim(vgsiname)=='amassk') cycle
- if(trim(vgsiname)=='pm2_5') cycle
- call getfv3lamfilevname(vgsiname,fv3filenamegin,filenamein2,varname)
- if(trim(filenamein) /= trim(filenamein2)) then
- write(6,*)'filenamein and filenamein2 are not the same as expected, stop'
- call flush(6)
- call stop2(333)
- endif
- ilev=grd_ionouv%lnames(1,ilevtot)
- nz=grd_ionouv%nsig
- nzp1=nz+1
- inative=nzp1-ilev
- countloc=(/nxcase,nycase,1/)
- startloc=(/1,1,inative/)
-
- work_a=hwork(1,:,:,ilevtot)
-
+ call mpi_allreduce(members,members_read,npe,mpi_integer,mpi_max,mpi_comm_world,ierror)
+ nread=0
+ mype_read_rank=-1
+ do i=1,npe
+ if (members_read(i) >= 0) then
+ nread=nread+1
+ mype_read_rank(nread) = members_read(i)
+ endif
+ enddo
- call check( nf90_inq_varid(gfile_loc,trim(varname),VarId) )
-
+ call setcomm(iworld,iworld_group,nread,mype_read_rank,mpi_comm_read,ierror)
- if(index(vgsiname,"delzinc") > 0) then
- if(fv3_io_layout_y > 1) then
+ if (procuse) then
+ if(fv3_io_layout_y > 1) then
+ allocate(gfile_loc_layout(0:fv3_io_layout_y-1))
do nio=0,fv3_io_layout_y-1
- countloc=(/nxcase,ny_layout_len(nio),1/)
- allocate(work_b_layout(nxcase,ny_layout_len(nio)))
- call check( nf90_get_var(gfile_loc_layout(nio),VarId,work_b_layout,start = startloc, count = countloc) )
- work_b(:,ny_layout_b(nio):ny_layout_e(nio))=work_b_layout
- deallocate(work_b_layout)
+ write(filename_layout,'(a,a,I4.4)') trim(filenamein),'.',nio
+ call check( nf90_open(filename_layout,ior(nf90_netcdf4,ior(nf90_write, nf90_mpiio)),gfile_loc_layout(nio),comm=mpi_comm_read,info=MPI_INFO_NULL) )
enddo
- else
- call check( nf90_get_var(gfile_loc,VarId,work_b,start = startloc, count = countloc) )
- endif
- call fv3_ll_to_h(work_a(:,:),workb2,nloncase,nlatcase,nlon_regional,nlat_regional,grid_reverse_flag)
- work_b(:,:)=work_b(:,:)+workb2(:,:)
- else
- if(add_saved)then
- if(fv3_io_layout_y > 1) then
+ gfile_loc=gfile_loc_layout(0)
+ else
+ call check( nf90_open(filenamein,ior(nf90_netcdf4,ior(nf90_write, nf90_mpiio)),gfile_loc,comm=mpi_comm_read,info=MPI_INFO_NULL) )
+ endif
+
+ do ilevtot=kbgn,kend
+ vgsiname=grd_ionouv%names(1,ilevtot)
+ if(trim(vgsiname)=='amassi') cycle
+ if(trim(vgsiname)=='amassj') cycle
+ if(trim(vgsiname)=='amassk') cycle
+ if(trim(vgsiname)=='pm2_5') cycle
+ call getfv3lamfilevname(vgsiname,fv3filenamegin,filenamein2,varname)
+ if(trim(filenamein) /= trim(filenamein2)) then
+ write(6,*)'filenamein and filenamein2 are not the same as expected, stop'
+ call stop2(333)
+ endif
+ ilev=grd_ionouv%lnames(1,ilevtot)
+ nz=grd_ionouv%nsig
+ nzp1=nz+1
+ inative=nzp1-ilev
+ countloc=(/nxcase,nycase,1,1/)
+ startloc=(/1,1,inative,1/)
+
+ work_a=hwork(1,:,:,ilevtot)
+
+ if( trim(varname) == 'ref_f3d' .or. trim(adjustl(varname)) == 'flash_extent_density' )then
+ iret=nf90_inquire_dimension(gfile_loc,1,name,len)
+ if(trim(name)=='xaxis_1') nx_phy=len
+ if( nx_phy == nxcase )then
+ allocate(work_b_tmp(nxcase,nycase))
+ countloc_tmp=(/nxcase,nycase,1,1/)
+ phy_smaller_domain = .false.
+ else
+ allocate(work_b_tmp(nxcase-6,nycase-6))
+ countloc_tmp=(/nxcase-6,nycase-6,1,1/)
+ phy_smaller_domain = .true.
+ end if
+ startloc_tmp=(/1,1,ilev,1/)
+ end if
+
+ call check( nf90_inq_varid(gfile_loc,trim(varname),VarId) )
+ call check( nf90_var_par_access(gfile_loc, VarId, nf90_independent))
+
+
+ if(index(vgsiname,"delzinc") > 0) then
+ if(fv3_io_layout_y > 1) then
+ do nio=0,fv3_io_layout_y-1
+ countloc=(/nxcase,ny_layout_len(nio),1,1/)
+ allocate(work_b_layout(nxcase,ny_layout_len(nio)))
+ call check( nf90_get_var(gfile_loc_layout(nio),VarId,work_b_layout,start = startloc, count = countloc) )
+ work_b(:,ny_layout_b(nio):ny_layout_e(nio))=work_b_layout
+ deallocate(work_b_layout)
+ enddo
+ else
+ call check( nf90_get_var(gfile_loc,VarId,work_b,start = startloc, count = countloc) )
+ endif
+ call fv3_ll_to_h(work_a(:,:),workb2,nloncase,nlatcase,nlon_regional,nlat_regional,grid_reverse_flag)
+ work_b(:,:)=work_b(:,:)+workb2(:,:)
+ else
+ if(add_saved)then
+ if(fv3_io_layout_y > 1) then
+ do nio=0,fv3_io_layout_y-1
+ countloc=(/nxcase,ny_layout_len(nio),1,1/)
+ allocate(work_b_layout(nxcase,ny_layout_len(nio)))
+ call check( nf90_get_var(gfile_loc_layout(nio),VarId,work_b_layout,start = startloc, count = countloc) )
+ work_b(:,ny_layout_b(nio):ny_layout_e(nio))=work_b_layout
+ deallocate(work_b_layout)
+ enddo
+ else
+ if( trim(varname) == 'ref_f3d' .or. trim(varname) == 'flash_extent_density' )then
+ work_b = 0.0_r_kind
+ call check( nf90_get_var(gfile_loc,VarId,work_b_tmp,start = startloc_tmp, count = countloc_tmp) )
+ where(work_b_tmp < 0.0_r_kind)
+ work_b_tmp = 0.0_r_kind
+ end where
+ if(phy_smaller_domain)then
+ work_b(4:nxcase-3,4:nycase-3) = work_b_tmp
+ else
+ work_b(1:nxcase,1:nycase) = work_b_tmp
+ end if
+ else
+ call check( nf90_get_var(gfile_loc,VarId,work_b,start = startloc, count = countloc) )
+ end if
+ endif
+ call fv3_h_to_ll(work_b(:,:),worka2,nlon_regional,nlat_regional,nloncase,nlatcase,grid_reverse_flag)
+!!!!!!!! analysis_inc: work_a !!!!!!!!!!!!!!!!
+ work_a(:,:)=work_a(:,:)-worka2(:,:)
+ call fv3_ll_to_h(work_a(:,:),workb2,nloncase,nlatcase,nlon_regional,nlat_regional,grid_reverse_flag)
+ work_b(:,:)=work_b(:,:)+workb2(:,:)
+ else
+ call fv3_ll_to_h(work_a(:,:),work_b(:,:),nloncase,nlatcase,nlon_regional,nlat_regional,grid_reverse_flag)
+ endif
+ endif
+ if (ifindstrloc(vnames_nonnegativetracers,trim(varname))> 0) then
+ where (work_b <0.0_r_kind) work_b=0.0_r_kind
+ endif
+ if(fv3_io_layout_y > 1) then
do nio=0,fv3_io_layout_y-1
- countloc=(/nxcase,ny_layout_len(nio),1/)
+ countloc=(/nxcase,ny_layout_len(nio),1,1/)
allocate(work_b_layout(nxcase,ny_layout_len(nio)))
- call check( nf90_get_var(gfile_loc_layout(nio),VarId,work_b_layout,start = startloc, count = countloc) )
- work_b(:,ny_layout_b(nio):ny_layout_e(nio))=work_b_layout
+ work_b_layout=work_b(:,ny_layout_b(nio):ny_layout_e(nio))
+ call check( nf90_put_var(gfile_loc_layout(nio),VarId,work_b_layout, start = startloc, count = countloc) )
deallocate(work_b_layout)
- enddo
- else
- call check( nf90_get_var(gfile_loc,VarId,work_b,start = startloc, count = countloc) )
- endif
- call fv3_h_to_ll(work_b(:,:),worka2,nlon_regional,nlat_regional,nloncase,nlatcase,grid_reverse_flag)
-!!!!!!!! analysis_inc: work_a !!!!!!!!!!!!!!!!
- work_a(:,:)=work_a(:,:)-worka2(:,:)
- call fv3_ll_to_h(work_a(:,:),workb2,nloncase,nlatcase,nlon_regional,nlat_regional,grid_reverse_flag)
- work_b(:,:)=work_b(:,:)+workb2(:,:)
- else
- call fv3_ll_to_h(work_a(:,:),work_b(:,:),nloncase,nlatcase,nlon_regional,nlat_regional,grid_reverse_flag)
- endif
- endif
- if(fv3_io_layout_y > 1) then
- do nio=0,fv3_io_layout_y-1
- countloc=(/nxcase,ny_layout_len(nio),1/)
- allocate(work_b_layout(nxcase,ny_layout_len(nio)))
- work_b_layout=work_b(:,ny_layout_b(nio):ny_layout_e(nio))
- call check( nf90_put_var(gfile_loc_layout(nio),VarId,work_b_layout, start = startloc, count = countloc) )
- deallocate(work_b_layout)
- enddo
- else
- call check( nf90_put_var(gfile_loc,VarId,work_b, start = startloc, count = countloc) )
- endif
-
- enddo !ilevtotl loop
- if(fv3_io_layout_y > 1) then
- do nio=0,fv3_io_layout_y-1
- call check(nf90_close(gfile_loc_layout(nio)))
- enddo
- deallocate(gfile_loc_layout)
- else
- call check(nf90_close(gfile_loc))
+ enddo
+ else
+ if( trim(varname) == 'ref_f3d' .or. trim(varname) == 'flash_extent_density' )then
+ if(phy_smaller_domain)then
+ work_b_tmp = work_b(4:nxcase-3,4:nycase-3)
+ else
+ work_b_tmp = work_b(1:nxcase,1:nycase)
+ end if
+ where(work_b_tmp < 0.0_r_kind)
+ work_b_tmp = 0.0_r_kind
+ end where
+ call check( nf90_put_var(gfile_loc,VarId,work_b_tmp, start = startloc_tmp, count = countloc_tmp) )
+ deallocate(work_b_tmp)
+ else
+ call check( nf90_put_var(gfile_loc,VarId,work_b, start = startloc, count = countloc) )
+ end if
+ endif
+
+ enddo !ilevtotl loop
+ if(fv3_io_layout_y > 1) then
+ do nio=0,fv3_io_layout_y-1
+ call check(nf90_close(gfile_loc_layout(nio)))
+ enddo
+ deallocate(gfile_loc_layout)
+ else
+ call check(nf90_close(gfile_loc))
+ endif
endif
+
+ call mpi_barrier(mpi_comm_world,ierror)
+
deallocate(work_b,work_a)
deallocate(workb2,worka2)
-
end subroutine gsi_fv3ncdf_write
subroutine check(status)
use kinds, only: i_kind
@@ -3774,23 +4933,25 @@ subroutine gsi_fv3ncdf_write_v1(grd_ionouv,cstate_nouv,add_saved,filenamein,fv3f
!
!$$$ end documentation block
- use mpimod, only: mpi_rtype,mpi_comm_world,mype,mpi_info_null
+ use mpimod, only: npe, setcomm,mpi_integer,mpi_max,mpi_rtype,mpi_comm_world,mype,mpi_info_null
use mod_fv3_lola, only: fv3_ll_to_h
use mod_fv3_lola, only: fv3_h_to_ll
use netcdf, only: nf90_open,nf90_close
- use netcdf, only: nf90_write,nf90_inq_varid
+ use netcdf, only: nf90_write, nf90_netcdf4,nf90_mpiio,nf90_inq_varid
use netcdf, only: nf90_put_var,nf90_get_var
+ use netcdf, only: nf90_independent,nf90_var_par_access
use gsi_bundlemod, only: gsi_bundle
use general_sub2grid_mod, only: sub2grid_info,general_sub2grid
implicit none
- type(sub2grid_info), intent(in):: grd_ionouv
- type(gsi_bundle),intent(inout) :: cstate_nouv
- logical ,intent(in ) :: add_saved
- character(*),intent(in):: filenamein
- type (type_fv3regfilenameg),intent (in) :: fv3filenamegin
+ type(sub2grid_info), intent(in) :: grd_ionouv
+ type(gsi_bundle), intent(inout):: cstate_nouv
+ logical, intent(in ):: add_saved
+ character(*), intent(in) :: filenamein
+ type (type_fv3regfilenameg),intent(in) :: fv3filenamegin
+
real(r_kind),dimension(1,grd_ionouv%nlat,grd_ionouv%nlon,grd_ionouv%kbegin_loc:grd_ionouv%kend_alloc):: hwork
- character(len=max_varname_length) :: filenamein2
+ character(len=max_filename_length) :: filenamein2
integer(i_kind) kbgn,kend
integer(i_kind) inative,ilev,ilevtot
@@ -3802,6 +4963,10 @@ subroutine gsi_fv3ncdf_write_v1(grd_ionouv,cstate_nouv,add_saved,filenamein,fv3f
character(len=max_varname_length) :: varname,vgsiname
integer(i_kind) nlatcase,nloncase,nxcase,nycase,countloc(3),startloc(3)
+ integer(i_kind):: iworld,iworld_group,nread,mpi_comm_read,i,ierror
+ integer(i_kind),dimension(npe):: members,members_read,mype_read_rank
+ logical:: procuse
+
mm1=mype+1
nloncase=grd_ionouv%nlon
@@ -3816,7 +4981,30 @@ subroutine gsi_fv3ncdf_write_v1(grd_ionouv,cstate_nouv,add_saved,filenamein,fv3f
allocate( work_b(nlon_regional,nlat_regional))
allocate( workb2(nlon_regional,nlat_regional))
allocate( worka2(nlatcase,nloncase))
- call check ( nf90_open(filenamein,nf90_write,gfile_loc,comm=mpi_comm_world,info=MPI_INFO_NULL)) !clt
+
+ procuse = .false.
+ members=-1
+ members_read=-1
+ if (kbgn<=kend) then
+ procuse = .true.
+ members(mm1) = mype
+ endif
+
+ call mpi_allreduce(members,members_read,npe,mpi_integer,mpi_max,mpi_comm_world,ierror)
+
+ nread=0
+ mype_read_rank=-1
+ do i=1,npe
+ if (members_read(i) >= 0) then
+ nread=nread+1
+ mype_read_rank(nread) = members_read(i)
+ endif
+ enddo
+
+ call setcomm(iworld,iworld_group,nread,mype_read_rank,mpi_comm_read,ierror)
+
+ if (procuse) then
+ call check ( nf90_open(filenamein,ior(nf90_netcdf4,ior(nf90_write, nf90_mpiio)),gfile_loc,comm=mpi_comm_read,info=MPI_INFO_NULL)) !clt
do ilevtot=kbgn,kend
vgsiname=grd_ionouv%names(1,ilevtot)
if(trim(vgsiname)=='amassi') cycle
@@ -3826,7 +5014,6 @@ subroutine gsi_fv3ncdf_write_v1(grd_ionouv,cstate_nouv,add_saved,filenamein,fv3f
call getfv3lamfilevname(vgsiname,fv3filenamegin,filenamein2,varname)
if(trim(filenamein) /= trim(filenamein2)) then
write(6,*)'filenamein and filenamein2 are not the same as expected, stop'
- call flush(6)
call stop2(333)
endif
ilev=grd_ionouv%lnames(1,ilevtot)
@@ -3840,6 +5027,7 @@ subroutine gsi_fv3ncdf_write_v1(grd_ionouv,cstate_nouv,add_saved,filenamein,fv3f
call check( nf90_inq_varid(gfile_loc,trim(varname),VarId) )
+ call check( nf90_var_par_access(gfile_loc, VarId, nf90_independent))
call check( nf90_get_var(gfile_loc,VarId,work_b,start=startloc,count=countloc) )
if(index(vgsiname,"delzinc") > 0) then
write(6,*)'delz is not in the cold start fiels with this option, incompatible setup , stop'
@@ -3857,9 +5045,13 @@ subroutine gsi_fv3ncdf_write_v1(grd_ionouv,cstate_nouv,add_saved,filenamein,fv3f
else
call fv3_ll_to_h(work_a(:,:),work_b(:,:),nloncase,nlatcase,nlon_regional,nlat_regional,grid_reverse_flag)
endif
+ if (ifindstrloc(vnames_nonnegativetracers,trim(varname))> 0) then
+ where (work_b <0.0_r_kind) work_b=0.0_r_kind
+ endif
call check( nf90_put_var(gfile_loc,VarId,work_b,start=startloc,count=countloc) )
enddo !ilevtot
call check(nf90_close(gfile_loc))
+ endif
deallocate(work_b,work_a)
deallocate(worka2,workb2)
@@ -3874,6 +5066,7 @@ subroutine reverse_grid_r(grid,nx,ny,nz)
implicit none
integer(i_kind), intent(in ) :: nx,ny,nz
real(r_kind), intent(inout ) :: grid(nx,ny,nz)
+
real(r_kind) :: tmp_grid(nx,ny)
integer(i_kind) :: i,j,k
!
@@ -3897,6 +5090,7 @@ subroutine reverse_grid_r_uv(grid,nx,ny,nz)
implicit none
integer(i_kind), intent(in ) :: nx,ny,nz
real(r_kind), intent(inout ) :: grid(nx,ny,nz)
+
real(r_kind) :: tmp_grid(nx,ny)
integer(i_kind) :: i,j,k
!
@@ -4313,13 +5507,13 @@ subroutine convert_cvpnx_to_nx(qnx_arr,cvpnr,cvpnr_pvalue,cloud_nt_updt,q_arr,qr
implicit none
- real(r_kind), intent(inout ) :: qnx_arr(lat2,lon2,nsig)
- logical, intent(in ) :: cvpnr
- real(r_kind), intent(in ) :: cvpnr_pvalue
- integer(i_kind), intent(in ) :: cloud_nt_updt
- real(r_kind), intent(in ) :: q_arr(lat2,lon2,nsig)
- real(r_kind), intent(in ) :: qr_arr(lat2,lon2,nsig)
- real(r_kind), intent(in ) :: ps_arr(lat2,lon2)
+ real(r_kind), intent(inout) :: qnx_arr(lat2,lon2,nsig)
+ logical, intent(in ) :: cvpnr
+ real(r_kind), intent(in ) :: cvpnr_pvalue
+ integer(i_kind), intent(in ) :: cloud_nt_updt
+ real(r_kind), intent(in ) :: q_arr(lat2,lon2,nsig)
+ real(r_kind), intent(in ) :: qr_arr(lat2,lon2,nsig)
+ real(r_kind), intent(in ) :: ps_arr(lat2,lon2)
real(r_kind), dimension(lat2,lon2,nsig) :: tmparr_qnr
integer(i_kind) :: i, j, k, it
@@ -4383,17 +5577,17 @@ subroutine gsi_copy_bundle(bundi,bundo)
! !INPUT PARAMETERS:
type(gsi_bundle), intent(in ) :: bundi
+ type(gsi_bundle), intent(inout) :: bundo
! !INPUT/OUTPUT PARAMETERS:
- type(gsi_bundle), intent(inout) :: bundo
character(len=max_varname_length),dimension(:),allocatable:: src_name_vars2d
character(len=max_varname_length),dimension(:),allocatable:: src_name_vars3d
character(len=max_varname_length),dimension(:),allocatable:: target_name_vars2d
character(len=max_varname_length),dimension(:),allocatable:: target_name_vars3d
character(len=max_varname_length) ::varname
real(r_kind),dimension(:,:,:),pointer:: pvar3d=>NULL()
- real(r_kind),dimension(:,:,:),pointer:: pvar2d =>NULL()
+ real(r_kind),dimension(:,:),pointer:: pvar2d =>NULL()
integer(i_kind):: src_nc3d,src_nc2d,target_nc3d,target_nc2d
integer(i_kind):: ivar,jvar,istatus
src_nc3d=bundi%n3d
@@ -4431,10 +5625,12 @@ subroutine gsi_copy_bundle(bundi,bundo)
return
end subroutine gsi_copy_bundle
subroutine getfv3lamfilevname(vgsinamein,fv3filenamegref,filenameout,vname)
+
type (type_fv3regfilenameg),intent (in) :: fv3filenamegref
- character(len=*):: vgsinamein
character(len=*),intent(out):: vname
character(len=*),intent(out):: filenameout
+ character(len=*),intent( in):: vgsinamein
+
if (ifindstrloc(vgsiname,vgsinamein)<= 0) then
write(6,*)'the name ',vgsinamein ,'cannot be treated correctly in getfv3lamfilevname,stop'
call stop2(333)
@@ -4443,6 +5639,8 @@ subroutine getfv3lamfilevname(vgsinamein,fv3filenamegref,filenameout,vname)
filenameout=fv3filenamegref%dynvars
else if(ifindstrloc(vartracers,vgsinamein)> 0 ) then
filenameout=fv3filenamegref%tracers
+ else if(ifindstrloc(varphyvars,vgsinamein)> 0) then
+ filenameout=fv3filenamegref%phyvars
else
write(6,*)'the filename corresponding to var ',trim(vgsinamein),' is not found, stop '
call stop2(333)
diff --git a/src/gsi/gsimod.F90 b/src/gsi/gsimod.F90
index 55d9298614..d7f5667252 100644
--- a/src/gsi/gsimod.F90
+++ b/src/gsi/gsimod.F90
@@ -21,13 +21,15 @@ module gsimod
lread_obs_save,lread_obs_skip,time_window_rad,tcp_posmatch,tcp_box, &
neutral_stability_windfact_2dvar,use_similarity_2dvar,ta2tb
use gsi_dbzOper, only: diag_radardbz
+ use gsi_fedOper, only: diag_fed
- use obsmod, only: doradaroneob,oneoblat,oneoblon,oneobheight,oneobvalue,oneobddiff,oneobradid,&
+ use obsmod, only: doradaroneob,dofedoneob,oneoblat,oneoblon,oneobheight,oneobvalue,oneobddiff,oneobradid,&
radar_no_thinning,ens_hx_dbz_cut,static_gsi_nopcp_dbz,rmesh_dbz,&
- rmesh_vr,zmesh_dbz,zmesh_vr,if_vterminal, if_model_dbz,if_vrobs_raw,&
- minobrangedbz,maxobrangedbz,maxobrangevr,maxtiltvr,missing_to_nopcp,&
+ rmesh_vr,zmesh_dbz,zmesh_vr,if_vterminal, if_model_dbz,if_model_fed,innov_use_model_fed,if_vrobs_raw,if_use_w_vr,&
+ minobrangedbz,maxobrangedbz,maxobrangevr,maxtiltvr,inflate_dbz_obserr,missing_to_nopcp,&
ntilt_radarfiles,whichradar,&
- minobrangevr,maxtiltdbz,mintiltvr,mintiltdbz,l2rwthin,hurricane_radar
+ minobrangevr,maxtiltdbz,mintiltvr,mintiltdbz,l2rwthin,hurricane_radar,&
+ r_hgt_fed
use obsmod, only: lwrite_predterms, &
lwrite_peakwt,use_limit,lrun_subdirs,l_foreaft_thin,lobsdiag_forenkf,&
@@ -91,15 +93,21 @@ module gsimod
erradar_inflate,tdrerr_inflate,use_poq7,qc_satwnds,&
init_qcvars,vadfile,noiqc,c_varqc,gps_jacqc,qc_noirjaco3,qc_noirjaco3_pole,&
buddycheck_t,buddydiag_save,njqc,vqc,nvqc,hub_norm,vadwnd_l2rw_qc, &
- pvis,pcldch,scale_cv,estvisoe,estcldchoe,vis_thres,cldch_thres,cao_check
+ pvis,pcldch,scale_cv,estvisoe,estcldchoe,vis_thres,cldch_thres,cao_check, &
+ cris_cads, iasi_cads, airs_cads
use qcmod, only: troflg,lat_c,nrand
+ use cads, only: M__Sensor,N__Num_Bands,N__GradChkInterval,N__Band_Size,N__Bands,N__Window_Width, &
+ N__Window_Bounds,R__BT_Threshold,R__Grad_Threshold,R__Window_Grad_Threshold, L__Do_Quick_Exit, &
+ L__Do_CrossBand, N__BandToUse,L__Do_Imager_Cloud_Detection, N__Num_Imager_Chans, &
+ N__Num_Imager_Clusters,N__Imager_Chans,R__Stddev_Threshold,R__Coverage_Threshold, &
+ R__FG_Departure_Threshold, CADS_Setup_Cloud
use pcpinfo, only: npredp,diag_pcp,dtphys,deltim,init_pcp
use jfunc, only: iout_iter,iguess,miter,factqmin,factqmax,superfact,limitqobs, &
factql,factqi,factqr,factqs,factqg, &
factv,factl,factp,factg,factw10m,facthowv,factcldch,niter,niter_no_qc,biascor,&
init_jfunc,qoption,cwoption,switch_on_derivatives,tendsflag,jiterstart,jiterend,R_option,&
bcoption,diurnalbc,print_diag_pcg,tsensible,diag_precon,step_start,pseudo_q2,&
- clip_supersaturation,cnvw_option
+ clip_supersaturation,cnvw_option,hofx_2m_sfcfile
use state_vectors, only: init_anasv,final_anasv
use control_vectors, only: init_anacv,final_anacv,nrf,nvars,nrf_3d,cvars3d,cvars2d,&
nrf_var,lcalc_gfdl_cfrac,incvars_to_zero,incvars_zero_strat,incvars_efold
@@ -151,8 +159,10 @@ module gsimod
readin_beta,use_localization_grid,use_gfs_ens,q_hyb_ens,i_en_perts_io, &
l_ens_in_diff_time,ensemble_path,ens_fast_read,sst_staticB,limqens, &
ntotensgrp,nsclgrp,naensgrp,ngvarloc,ntlevs_ens,naensloc, &
- i_ensloccov4tim,i_ensloccov4var,i_ensloccov4scl,l_timloc_opt
- use hybrid_ensemble_parameters,only : l_both_fv3sar_gfs_ens,n_ens_gfs,n_ens_fv3sar
+ r_ensloccov4tim,r_ensloccov4var,r_ensloccov4scl,l_timloc_opt,&
+ vdl_scale,vloc_varlist,&
+ global_spectral_filter_sd,assign_vdl_nml,parallelization_over_ensmembers,l_mgbf_loc
+ use hybrid_ensemble_parameters,only : l_both_fv3sar_gfs_ens,n_ens_gfs,n_ens_fv3sar,weight_ens_gfs,weight_ens_fv3sar
use rapidrefresh_cldsurf_mod, only: init_rapidrefresh_cldsurf, &
dfi_radar_latent_heat_time_period,metar_impact_radius,&
metar_impact_radius_lowcloud,l_gsd_terrain_match_surftobs, &
@@ -173,17 +183,21 @@ module gsimod
i_coastline,i_gsdqc,qv_max_inc,ioption,l_precip_clear_only,l_fog_off,&
cld_bld_coverage,cld_clr_coverage,&
i_cloud_q_innovation,i_ens_mean,DTsTmax,&
- i_T_Q_adjust,l_saturate_bkCloud,l_rtma3d,i_precip_vertical_check
+ i_T_Q_adjust,l_saturate_bkCloud,l_rtma3d,i_precip_vertical_check, &
+ corp_howv, hwllp_howv, corp_gust, hwllp_gust, oerr_gust
use gsi_metguess_mod, only: gsi_metguess_init,gsi_metguess_final
use gsi_chemguess_mod, only: gsi_chemguess_init,gsi_chemguess_final
use tcv_mod, only: init_tcps_errvals,tcp_refps,tcp_width,tcp_ermin,tcp_ermax
use chemmod, only : init_chem,berror_chem,berror_fv3_cmaq_regional,oneobtest_chem,&
+ berror_fv3_sd_regional,&
maginnov_chem,magoberr_chem,&
oneob_type_chem,oblat_chem,&
+ anowbufr_ext,&
oblon_chem,obpres_chem,diag_incr,elev_tolerance,tunable_error,&
in_fname,out_fname,incr_fname, &
laeroana_gocart, l_aoderr_table, aod_qa_limit, luse_deepblue, lread_ext_aerosol, &
- laeroana_fv3cmaq,laeroana_fv3smoke,pm2_5_innov_threshold,crtm_aerosol_model,crtm_aerosolcoeff_format,crtm_aerosolcoeff_file, &
+ laeroana_fv3cmaq,laeroana_fv3smoke,pm2_5_innov_threshold,pm2_5_urban_innov_threshold,pm2_5_bg_threshold,&
+ crtm_aerosol_model,crtm_aerosolcoeff_format,crtm_aerosolcoeff_file, &
icvt_cmaq_fv3, raod_radius_mean_scale,raod_radius_std_scale
use chemmod, only : wrf_pm2_5,aero_ratios
@@ -195,7 +209,7 @@ module gsimod
use gsi_nstcouplermod, only: gsi_nstcoupler_init_nml
use gsi_nstcouplermod, only: nst_gsi,nstinfo,zsea1,zsea2,fac_dtl,fac_tsl
use ncepnems_io, only: init_nems,imp_physics,lupp
- use wrf_vars_mod, only: init_wrf_vars
+ use wrf_vars_mod, only: init_wrf_vars,fed_exist,dbz_exist
use gsi_rfv3io_mod,only : fv3sar_bg_opt
use radarz_cst, only: mphyopt, MFflg
use radarz_iface, only: init_mphyopt
@@ -499,7 +513,23 @@ module gsimod
! 2. fv3_regional = .true.
! 3. fv3_cmaq_regional = .true.
! 4. berror_fv3_cmaq_regional = .true.
+! 09-02-2022 Jung Added namelist entries to call a new IR cloud detection routine
+! the original cloud detection routine is the default. To use the new
+! cloud detection routine, set the flags to .true.
! 09-15-2022 yokota - add scale/variable/time-dependent localization
+! 2023-07-30 Zhao - added namelist options for analysis of significant wave height
+! (aka howv in GSI code): corp_howv, hwllp_howv
+! (in namelist session rapidrefresh_cldsurf)
+!
+! 2023-09-14 H. Wang - add namelist option for FED EnVar DA.
+! - if_model_fed=.true. : FED in background and ens. If
+! perform FED DA, this has to be true along with fed in
+! control/analysis and metguess vectors. If only run GSI observer,
+! it can be false.
+! - innov_use_model_fed=.true. : Use FED from BG to calculate innovation.
+! this requires if_model_fed=.true.
+! it works either an EnVar DA run or a GSI observer run.
+! 02-20-2024 yokota - add MGBF-based localization
!
!EOP
!-------------------------------------------------------------------------
@@ -558,6 +588,7 @@ module gsimod
! diag_co - logical to turn off or on the diagnostic carbon monoxide file (true=on)
! diag_light - logical to turn off or on the diagnostic lightning file (true=on)
! diag_radardbz - logical to turn off or on the diagnostic radar reflectivity file (true=on)
+! diag_fed - logical to turn off or on the diagnostic flash extent density file (true=on)
! write_diag - logical to write out diagnostic files on outer iteration
! lobsdiagsave - write out additional observation diagnostics
! ltlint - linearize inner loop
@@ -723,6 +754,10 @@ module gsimod
! optconv - downweighting option for iasi and cris for moisture channels to
! improve convergence. default 0.0 (no change). Larger number improves
! convergence.
+! inflate_dbz_obserr - logical that controls inflation of reflectivity ob error
+! for obs that exceed gross error magnitude
+! if true, inflate ob error
+! if false, reject ob
!
! NOTE: for now, if in regional mode, then iguess=-1 is forced internally.
! add use of guess file later for regional mode.
@@ -736,8 +771,8 @@ module gsimod
min_offset,pseudo_q2,&
iout_iter,npredp,retrieval,&
tzr_qc,tzr_bufrsave,&
- diag_rad,diag_pcp,diag_conv,diag_ozone,diag_aero,diag_co,diag_light,diag_radardbz,iguess, &
- write_diag,reduce_diag, &
+ diag_rad,diag_pcp,diag_conv,diag_ozone,diag_aero,diag_co,diag_light,diag_radardbz,diag_fed, &
+ iguess,write_diag,reduce_diag, &
oneobtest,sfcmodel,dtbduv_on,ifact10,l_foto,offtime_data,&
use_pbl,use_compress,nsig_ext,gpstop,commgpstop, commgpserrinf, &
perturb_obs,perturb_fact,oberror_tune,preserve_restart_date, &
@@ -758,17 +793,18 @@ module gsimod
use_gfs_stratosphere,pblend0,pblend1,step_start,diag_precon,lrun_subdirs,&
use_sp_eqspace,lnested_loops,lsingleradob,thin4d,use_readin_anl_sfcmask,&
luse_obsdiag,id_drifter,id_ship,verbose,print_obs_para,lsingleradar,singleradar,lnobalance, &
- missing_to_nopcp,minobrangedbz,minobrangedbz,maxobrangedbz,&
- maxobrangevr,maxtiltvr,whichradar,doradaroneob,oneoblat,&
+ inflate_dbz_obserr,missing_to_nopcp,minobrangedbz,minobrangedbz,maxobrangedbz,&
+ maxobrangevr,maxtiltvr,whichradar,doradaroneob,dofedoneob,oneoblat,&
oneoblon,oneobheight,oneobvalue,oneobddiff,oneobradid,&
rmesh_vr,zmesh_dbz,zmesh_vr, ntilt_radarfiles, whichradar,&
radar_no_thinning,ens_hx_dbz_cut,static_gsi_nopcp_dbz,rmesh_dbz,&
- minobrangevr, maxtiltdbz, mintiltvr,mintiltdbz,if_vterminal,if_vrobs_raw,&
- if_model_dbz,imp_physics,lupp,netcdf_diag,binary_diag,l_wcp_cwm,aircraft_recon,diag_version,&
+ minobrangevr, maxtiltdbz, mintiltvr,mintiltdbz,if_vterminal,if_vrobs_raw,if_use_w_vr,&
+ if_model_dbz,if_model_fed,innov_use_model_fed,imp_physics,lupp,netcdf_diag,binary_diag,l_wcp_cwm,aircraft_recon,diag_version,&
write_fv3_incr,incvars_to_zero,incvars_zero_strat,incvars_efold,diag_version,&
cao_check,lcalc_gfdl_cfrac,tau_fcst,efsoi_order,lupdqc,lqcoef,cnvw_option,l2rwthin,hurricane_radar,&
l_reg_update_hydro_delz, l_obsprvdiag,&
- l_use_dbz_directDA, l_use_rw_columntilt, ta2tb, optconv
+ l_use_dbz_directDA, l_use_rw_columntilt, ta2tb, optconv, &
+ r_hgt_fed
! GRIDOPTS (grid setup variables,including regional specific variables):
! jcap - spectral resolution
@@ -1025,6 +1061,13 @@ module gsimod
! wind observations.
! vad_near_analtime - assimilate newvadwnd obs around analysis time only
+!
+! Flags to use the new IR cloud detection routine. Flag must be set to true to use the new routine. The default
+! (no flag or .false.) will use the default.
+! airs_cads: use the clod and aerosool detection software for the AIRS instrument
+! cris_cads: use the cloud and aerosol detection software for CrIS instruments
+! iasi_cads: use the cloud and aerosol detection software for IASI instruments
+!
namelist/obsqc/dfact,dfact1,erradar_inflate,tdrerr_inflate,oberrflg,&
vadfile,noiqc,c_varqc,blacklst,use_poq7,hilbert_curve,tcp_refps,tcp_width,&
@@ -1035,7 +1078,7 @@ module gsimod
q_doe_a_136,q_doe_a_137,q_doe_b_136,q_doe_b_137, &
t_doe_a_136,t_doe_a_137,t_doe_b_136,t_doe_b_137, &
uv_doe_a_236,uv_doe_a_237,uv_doe_a_213,uv_doe_b_236,uv_doe_b_237,uv_doe_b_213, &
- vad_near_analtime
+ vad_near_analtime,airs_cads,cris_cads,iasi_cads
! OBS_INPUT (controls input data):
! dmesh(max(dthin))- thinning mesh for each group
@@ -1045,7 +1088,7 @@ module gsimod
! l_foreaft_thin - separate TDR fore/aft scan for thinning
namelist/obs_input/dmesh,time_window_max,time_window_rad, &
- ext_sonde,l_foreaft_thin
+ ext_sonde,l_foreaft_thin,hofx_2m_sfcfile
! SINGLEOB_TEST (one observation test case setup):
! maginnov - magnitude of innovation for one ob
@@ -1366,23 +1409,62 @@ module gsimod
! l_timloc_opt - if true, then turn on time-dependent localization
! ngvarloc - number of variable-dependent localization lengths
! naensloc - total number of spatial localization lengths and scale separation lengths (should be naensgrp+nsclgrp-1)
-! i_ensloccov4tim - flag of cross-temporal localization
-! =0: cross-temporal covariance is retained
-! =1: cross-temporal covariance is zero
-! i_ensloccov4var - flag of cross-variable localization
-! =0: cross-variable covariance is retained
-! =1: cross-variable covariance is zero
-! i_ensloccov4scl - flag of cross-scale localization
-! =0: cross-scale covariance is retained
-! =1: cross-scale covariance is zero
+! r_ensloccov4tim - factor multiplying to cross-time covariance
+! For example,
+! =0.0: cross-time covariance is decreased to zero
+! =0.5: cross-time covariance is decreased to half
+! =1.0: cross-time covariance is retained
+! r_ensloccov4var - factor multiplying to cross-variable covariance
+! For example,
+! =0.0: cross-variable covariance is decreased to zero
+! =0.5: cross-variable covariance is decreased to half
+! =1.0: cross-variable covariance is retained
+! r_ensloccov4scl - factor multiplying to cross-scale covariance
+! For example,
+! =0.0: cross-scale covariance is decreased to zero
+! =0.5: cross-scale covariance is decreased to half
+! =1.0: cross-scale covariance is retained
+! global_spectral_filter_sd - if true, use spectral filter function for
+! scale decomposition in the global application (Huang et al. 2021)
+! assign_vdl_nml - if true, vdl_scale, and vloc_varlist will be used for
+! assigning variable-dependent localization upon SDL in gsiparm.anl.
+! This method described in (Wang and Wang 2022, JAMES) is
+! equivalent to, but different from the method associated
+! with the parameter r_ensloccov4var.
+! vloc_varlist - list of control variables using the same localization length,
+! effective only with assign_vdl_nml=.true. For example,
+! vloc_varlist(1,:) = 'sf','vp','ps','t',
+! vloc_varlist(2,:) = 'q',
+! vloc_varlist(3,:) = 'qr','qs','qg','dbz','w','ql','qi',
+! vloc_varlist(4,:) = 'sf','vp','ps','t','q',
+! vloc_varlist(5,:) = 'qr','qs','qg','dbz','w','ql','qi',
+! This example indicates that 3 variable-groups will be adopted for VDL.
+! 'sf','vp','ps','t' will share the same localization length of v1L1;
+! 'q' will have the localization lenth of v2L1
+! 'qr','qs','qg','dbz','w','ql','qi', use the same localization length of v3L1
!
- namelist/hybrid_ensemble/l_hyb_ens,uv_hyb_ens,q_hyb_ens,aniso_a_en,generate_ens,n_ens,l_both_fv3sar_gfs_ens,n_ens_gfs,n_ens_fv3sar,nlon_ens,nlat_ens,jcap_ens,&
+! For L2, a different configuration of VDL can be applied:
+! ~~~~~~~~~
+! 'sf','vp','ps','t','q' will share the same localization length of v2L2;
+! 'qr','qs','qg','dbz','w','ql','qi', use the same localization length of v2L2
+! vdl_scale - number of variables in each variable-group, effective only with assign_vdl_nml=.true.
+! if 3 variable-groups with 2 separated scale is set,
+! vdl_scale = 3, 3, 3, 2, 2
+! ^ ^ ^ ^ ^
+! s_ens_h = v1L1 v2L1 v3L1 v1L2 v2L2
+! Then localization lengths will be assigned as above.
+! l_mgbf_loc - if true, multi-grid beta filter is used for localization instead of recursive filter
+!
+ namelist/hybrid_ensemble/l_hyb_ens,uv_hyb_ens,q_hyb_ens,aniso_a_en,generate_ens,n_ens,&
+ l_both_fv3sar_gfs_ens,n_ens_gfs,n_ens_fv3sar,weight_ens_gfs,weight_ens_fv3sar,nlon_ens,nlat_ens,jcap_ens,&
pseudo_hybens,merge_two_grid_ensperts,regional_ensemble_option,fv3sar_bg_opt,fv3sar_ensemble_opt,full_ensemble,pwgtflg,&
jcap_ens_test,beta_s0,beta_e0,s_ens_h,s_ens_v,readin_localization,eqspace_ensgrid,readin_beta,&
grid_ratio_ens, &
oz_univ_static,write_ens_sprd,use_localization_grid,use_gfs_ens, &
i_en_perts_io,l_ens_in_diff_time,ensemble_path,ens_fast_read,sst_staticB,limqens, &
- nsclgrp,l_timloc_opt,ngvarloc,naensloc,i_ensloccov4tim,i_ensloccov4var,i_ensloccov4scl
+ nsclgrp,l_timloc_opt,ngvarloc,naensloc,r_ensloccov4tim,r_ensloccov4var,r_ensloccov4scl,&
+ vdl_scale,vloc_varlist,&
+ global_spectral_filter_sd,assign_vdl_nml,parallelization_over_ensmembers,l_mgbf_loc
! rapidrefresh_cldsurf (options for cloud analysis and surface
! enhancement for RR appilcation ):
@@ -1518,6 +1600,13 @@ module gsimod
! = 2(clean Qg as in 1, and adjustment to the retrieved Qr/Qs/Qnr throughout the whole profile)
! = 3(similar to 2, but adjustment to Qr/Qs/Qnr only below maximum reflectivity level
! and where the dbz_obs is missing);
+! corp_howv - real, static background error of howv (stddev error)
+! = 0.42 meters (default)
+! hwllp_howv - real, background error de-correlation length scale of howv
+! = 170,000.0 meters (default 170 km)
+! corp_gust - real, static background error of gust (stddev error)
+! hwllp_gust - real, background error de-correlation length scale of gust
+! oerr_gust - real, observation error of gust
!
namelist/rapidrefresh_cldsurf/dfi_radar_latent_heat_time_period, &
metar_impact_radius,metar_impact_radius_lowcloud, &
@@ -1538,11 +1627,18 @@ module gsimod
i_coastline,i_gsdqc,qv_max_inc,ioption,l_precip_clear_only,l_fog_off,&
cld_bld_coverage,cld_clr_coverage,&
i_cloud_q_innovation,i_ens_mean,DTsTmax, &
- i_T_Q_adjust,l_saturate_bkCloud,l_rtma3d,i_precip_vertical_check
+ i_T_Q_adjust,l_saturate_bkCloud,l_rtma3d,i_precip_vertical_check, &
+ corp_howv, hwllp_howv, corp_gust, hwllp_gust, oerr_gust
! chem(options for gsi chem analysis) :
! berror_chem - .true. when background for chemical species that require
! conversion to lower case and/or species names longer than 5 chars
+! berror_fv3_cmaq_regional - .true. use background error stat for online
+! RRFS_CMAQ model. Control variable
+! names extended up to 10 chars
+! berror_fv3_sd_regional - .true. use background error stat for online
+! RRFS_SD model. Control variable
+! names extended up to 10 chars
! oneobtest_chem - one-ob trigger for chem constituent analysis
! maginnov_chem - O-B make-believe residual for one-ob chem test
! magoberr_chem - make-believe obs error for one-ob chem test
@@ -1564,13 +1660,15 @@ module gsimod
! luse_deepblue - whether to use MODIS AOD from the deepblue algorithm
! lread_ext_aerosol - if true, reads aerfNN file for aerosol arrays rather than sigfNN (NGAC NEMS IO)
- namelist/chem/berror_chem,berror_fv3_cmaq_regional,oneobtest_chem,maginnov_chem,magoberr_chem,&
+ namelist/chem/berror_chem,berror_fv3_cmaq_regional,berror_fv3_sd_regional,&
+ oneobtest_chem,anowbufr_ext,maginnov_chem,magoberr_chem,&
oneob_type_chem,oblat_chem,oblon_chem,obpres_chem,&
diag_incr,elev_tolerance,tunable_error,&
in_fname,out_fname,incr_fname,&
laeroana_gocart, laeroana_fv3cmaq,laeroana_fv3smoke,l_aoderr_table, aod_qa_limit, &
crtm_aerosol_model,crtm_aerosolcoeff_format,crtm_aerosolcoeff_file, &
icvt_cmaq_fv3,pm2_5_innov_threshold, &
+ pm2_5_innov_threshold,pm2_5_urban_innov_threshold,pm2_5_bg_threshold,&
raod_radius_mean_scale,raod_radius_std_scale, luse_deepblue,&
aero_ratios,wrf_pm2_5, lread_ext_aerosol
@@ -1586,6 +1684,40 @@ module gsimod
! fac_tsl - index to apply thermal skin layer or not: 0 = no; 1 = yes.
namelist/nst/nst_gsi,nstinfo,zsea1,zsea2,fac_dtl,fac_tsl
+! Initialize the Cloud and Aerosol Detection Software (CADS)
+!
+! M__Sensor Unique ID for sensor
+! N__Num_Bands Number of channel bands
+! N__Band_Size(:) Number of channels in each band
+! N__Bands(:,:) Channel lists
+! N__Window_Width(:) Smoothing filter window widths per band
+! N__Window_Bounds(:,:) Channels in the spectral window gradient check
+! N__GradChkInterval(:) Window width used in gradient calculation
+! R__BT_Threshold(:) BT threshold for cloud contamination
+! R__Grad_Threshold(:) Gradient threshold for cloud contamination
+! R__Window_Grad_Threshold(:) Threshold for window gradient check in QE
+! L__Do_Quick_Exit On/off switch for the Quick Exit scenario
+! L__Do_CrossBand On/off switch for the cross-band method
+! N__BandToUse(:) Band number assignment for each channel
+! L__Do_Imager_Cloud_Detection On/off switch for the imager cloud detection
+! N__Num_Imager_Chans No. of imager channels
+! N__Num_Imager_Clusters No. of clusters to be expected
+! N__Imager_Chans(:) List of imager channels
+! R__Stddev_Threshold(:) St. Dev. threshold, one for each imager channel
+! R__Coverage_Threshold Threshold for fractional coverage of a cluster
+! R__FG_Departure_Threshold Threshold for imager FG departure
+
+ NAMELIST / Cloud_Detect_Coeffs / M__Sensor, N__Num_Bands, &
+ N__Band_Size, N__Bands, N__Window_Width, N__Window_Bounds, &
+ N__GradChkInterval, R__BT_Threshold, R__Grad_Threshold, &
+ R__Window_Grad_Threshold, L__Do_Quick_Exit, &
+ L__Do_CrossBand, N__BandToUse, &
+ L__Do_Imager_Cloud_Detection, N__Num_Imager_Chans, &
+ N__Num_Imager_Clusters, N__Imager_Chans, &
+ R__Stddev_Threshold, R__Coverage_Threshold, &
+ R__FG_Departure_Threshold
+
+
!EOC
!---------------------------------------------------------------------------
@@ -1672,6 +1804,7 @@ subroutine gsimain_initialize
call set_fgrid2agrid
call gsi_nstcoupler_init_nml
call init_radaruse_directDA
+ call CADS_Setup_Cloud
if(mype==0) write(6,*)' at 0 in gsimod, use_gfs_stratosphere,nems_nmmb_regional = ', &
use_gfs_stratosphere,nems_nmmb_regional
@@ -1785,9 +1918,10 @@ subroutine gsimain_initialize
n_ens_gfs=n_ens
n_ens_fv3sar=0
else
- write(6,*)'n_ens_gfs and n_ens_fv3sar won"t be used if not regional_ensemble_option==5'
+ if(mype == 0)write(6,*)'n_ens_gfs and n_ens_fv3sar won"t be used if not regional_ensemble_option==5'
endif
-
+ weight_ens_gfs=one
+ weight_ens_fv3sar=one
endif
if(ltlint) then
if(vqc .or. njqc .or. nvqc)then
@@ -1839,7 +1973,9 @@ subroutine gsimain_initialize
else
naensgrp=ntotensgrp
endif
- if(naensloc 0 and if_model_fed=.true.',332)
+ end if
+
+ if (.not. (miter == 0 .or. lobserver) .and. if_model_dbz .and. .not. dbz_exist) then
+ if(mype==0) write(6,*)' GSIMOD: .not. (miter == 0 .or. lobserver) and if_model_dbz=.true. but dbz is not in anavinfo file'
+ call die(myname_,'Please check namelist parameters and/or add dbz in anavinfo (contro/state_vector and met_guess) when miter > 0 and if_model_fed=.true.',334)
+ end if
! Ensure valid number of horizontal scales
if (nhscrf<0 .or. nhscrf>3) then
@@ -1934,6 +2096,7 @@ subroutine gsimain_initialize
diag_pcp=.false.
diag_light=.false.
diag_radardbz=.false.
+ diag_fed=.false.
use_limit = 0
end if
if(reduce_diag) use_limit = 0
@@ -2002,15 +2165,17 @@ subroutine gsimain_initialize
baldiag_inc =.false.
end if
-! If reflectivity is intended to be assimilated, beta_s0 should be zero.
+! Warning of reflectivity assimilation with static B
if ( beta_s0 > 0.0_r_kind )then
! skipped in case of direct reflectivity DA because it works in Envar and hybrid
if ( l_use_rw_columntilt .or. l_use_dbz_directDA) then
do i=1,ndat
- if ( index(dtype(i), 'dbz') /= 0 )then
- write(6,*)'beta_s0 needs to be set to zero in this GSI version, when reflectivity is directly assimilated. &
- Static B extended for radar reflectivity assimilation will be included in future version.'
- call stop2(8888)
+ if ( if_model_dbz .and. (index(dtype(i), 'dbz') /= 0) )then
+ if (mype==0) then
+ write(6,*)'GSIMOD: ***WARNING*** static B for reflectivity is regarded as zero in this GSI version &
+ even though beta_s0 =',beta_s0
+ write(6,*)'Static B extended for radar reflectivity assimilation will be included in future version.'
+ end if
end if
end do
end if
@@ -2168,7 +2333,7 @@ subroutine gsimain_initialize
endif
! Set up directories (or pe specific filenames)
- call init_directories(mype)
+ call init_directories(mype,npe)
! Initialize space for qc
call create_qcvars
diff --git a/src/gsi/gsisub.F90 b/src/gsi/gsisub.F90
index 6aef101f55..94489266ba 100644
--- a/src/gsi/gsisub.F90
+++ b/src/gsi/gsisub.F90
@@ -194,7 +194,7 @@ subroutine gsisub(init_pass,last_pass)
end if
if(last_pass) call observer_finalize()
#ifndef HAVE_ESMF
- call destroy_gesfinfo() ! paired with gesinfo()
+ call destroy_gesfinfo() ! paired with gesinfo()
#endif
else
call glbsoi
diff --git a/src/gsi/guess_grids.F90 b/src/gsi/guess_grids.F90
index e19ce93638..0601959aad 100644
--- a/src/gsi/guess_grids.F90
+++ b/src/gsi/guess_grids.F90
@@ -977,18 +977,29 @@ subroutine create_gesfinfo
nfldaer_all=nfldaer
nfldaer_now=0
extrap_intime=.true.
- allocate(hrdifsfc(nfldsfc),ifilesfc(nfldsfc), &
- hrdifnst(nfldnst),ifilenst(nfldnst), &
- hrdifsig(nfldsig),ifilesig(nfldsig), &
- hrdifaer(nfldaer),ifileaer(nfldaer), &
- hrdifsfc_all(nfldsfc_all), &
- hrdifnst_all(nfldnst_all), &
- hrdifsig_all(nfldsig_all), &
- hrdifaer_all(nfldaer_all), &
- stat=istatus)
+ if(nfldsig>0) allocate(hrdifsig(nfldsig),ifilesig(nfldsig), &
+ hrdifsig_all(nfldsig_all), &
+ stat=istatus)
if (istatus/=0) &
- write(6,*)'CREATE_GESFINFO(hrdifsfc,..): allocate error, istatus=',&
- istatus
+ call die('CREATE_GESFINFO', '(hrdifsig,..): allocate error, istatus=', istatus)
+ if(nfldsfc>0) allocate(hrdifsfc(nfldsfc),ifilesfc(nfldsfc), &
+ hrdifsfc_all(nfldsfc_all), &
+ stat=istatus)
+ if (istatus/=0) &
+ call die('CREATE_GESFINFO', '(hrdifsfc,..): allocate error, istatus=',&
+ istatus)
+ if(nfldnst>0) allocate(hrdifnst(nfldnst),ifilenst(nfldnst), &
+ hrdifnst_all(nfldnst_all), &
+ stat=istatus)
+ if (istatus/=0) &
+ call die('CREATE_GESFINFO', '(hrdifnst,..): allocate error, istatus=',&
+ istatus)
+ if(nfldnst>0) allocate(hrdifaer(nfldaer),ifileaer(nfldaer), &
+ hrdifaer_all(nfldaer_all), &
+ stat=istatus)
+ if (istatus/=0) &
+ call die('CREATE_GESFINFO', '(hrdifaer,..): allocate error, istatus=',&
+ istatus)
#endif /* HAVE_ESMF */
return
@@ -1030,11 +1041,18 @@ subroutine destroy_gesfinfo
gesfinfo_created_=.false.
#ifndef HAVE_ESMF
- deallocate(hrdifsfc,ifilesfc,hrdifnst,hrdifaer,ifilenst,hrdifsig,ifilesig,ifileaer,&
- hrdifsfc_all,hrdifnst_all,hrdifsig_all,hrdifaer_all,stat=istatus)
+ if(nfldsig>0) deallocate(hrdifsig,ifilesig,hrdifsig_all,stat=istatus)
if (istatus/=0) &
- write(6,*)'DESTROY_GESFINFO: deallocate error, istatus=',&
- istatus
+ call die('DESTROY_GESFINFO', 'deallocate error, istatus=',istatus)
+ if(nfldsfc>0) deallocate(hrdifsfc,ifilesfc,hrdifsfc_all,stat=istatus)
+ if (istatus/=0) &
+ call die('DESTROY_GESFINFO', 'deallocate error, istatus=',istatus)
+ if(nfldnst>0) deallocate(hrdifnst,ifilenst,hrdifnst_all,stat=istatus)
+ if (istatus/=0) &
+ call die('DESTROY_GESFINFO', 'deallocate error, istatus=',istatus)
+ if(nfldnst>0) deallocate(hrdifaer,ifileaer,hrdifaer_all,stat=istatus)
+ if (istatus/=0) &
+ call die('DESTROY_GESFINFO', 'deallocate error, istatus=',istatus)
nfldsfc_all=0
nfldnst_all=0
@@ -1765,7 +1783,7 @@ subroutine load_gsdpbl_hgt(mype)
k=1
DO while (abs(pbl_height(i,j,jj)) < 0.0001_r_kind)
if( thetav(k) > thsfc + 1.0_r_kind ) then
- pbl_height(i,j,jj) = float(k) - (thetav(k) - (thsfc + 1.0_r_kind))/ &
+ pbl_height(i,j,jj) = real(k,r_kind) - (thetav(k) - (thsfc + 1.0_r_kind))/ &
max((thetav(k)-thetav(k-1)),0.01_r_kind)
endif
k=k+1
@@ -2300,7 +2318,7 @@ subroutine guess_grids_stats3d_(name,a,mype)
end do
end do
end do
- work_a(nsig+1)=float(lon1*lat1)
+ work_a(nsig+1)=real(lon1*lat1,r_kind)
call mpi_allreduce(work_a,work_a1,nsig+1,mpi_rtype,mpi_sum,&
mpi_comm_world,ierror)
@@ -2368,7 +2386,7 @@ subroutine guess_grids_stats2d_(name,a,mype)
work_a(1) = work_a(1) + a(i,j)
end do
end do
- work_a(2)=float(lon1*lat1)
+ work_a(2)=real(lon1*lat1,r_kind)
call mpi_allreduce(work_a,work_a1,2,mpi_rtype,mpi_sum,&
mpi_comm_world,ierror)
diff --git a/src/gsi/hdraobmod.f90 b/src/gsi/hdraobmod.f90
index 00abeb66be..3444c96fcc 100644
--- a/src/gsi/hdraobmod.f90
+++ b/src/gsi/hdraobmod.f90
@@ -188,7 +188,7 @@ subroutine read_hdraob(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
real(r_kind),dimension(nsig):: presl,hgtl
real(r_kind),dimension(nsig-1):: dpres
real(r_kind),dimension(maxlevs)::plevs
- real(r_kind),allocatable,dimension(:,:):: cdata_all,cdata_out
+ real(r_kind),allocatable,dimension(:,:):: cdata_all
real(r_kind) :: missing
real(r_double) rstation_id,r_station
@@ -580,7 +580,7 @@ subroutine read_hdraob(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! Add obs reference time, then subtract analysis time to get obs
! time relative to analysis
- time_correction=float(minobs-minan)*r60inv
+ time_correction=real(minobs-minan,r_kind)*r60inv
else
time_correction=zero
@@ -1271,20 +1271,13 @@ subroutine read_hdraob(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
close(lunin)
! Write header record and data to output file for further processing
- allocate(cdata_out(nreal,ndata))
- do i=1,ndata
- do k=1,nreal
- cdata_out(k,i)=cdata_all(k,i)
- end do
- end do
- deallocate(cdata_all)
- call count_obs(ndata,nreal,ilat,ilon,cdata_out,nobs)
+ call count_obs(ndata,nreal,ilat,ilon,cdata_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon,ndata
- write(lunout) cdata_out
+ write(lunout) ((cdata_all(k,i),k=1,nreal),i=1,ndata)
- deallocate(cdata_out)
+ deallocate(cdata_all)
if(diagnostic_reg .and. ntest>0) write(6,*)'READ_HDRAOB: ',&
'ntest,disterrmax=',ntest,disterrmax
diff --git a/src/gsi/hybrid_ensemble_isotropic.F90 b/src/gsi/hybrid_ensemble_isotropic.F90
index 3fa827f1f6..87f3605eaf 100644
--- a/src/gsi/hybrid_ensemble_isotropic.F90
+++ b/src/gsi/hybrid_ensemble_isotropic.F90
@@ -49,6 +49,7 @@ module hybrid_ensemble_isotropic
! 2016-05-13 parrish - remove beta12mult
! 2018-02-15 wu - add code for fv3_regional option
! 2022-09-15 yokota - add scale/variable/time-dependent localization
+! 2024-02-20 yokota - add MGBF-based localization
!
! subroutines included:
! sub init_rf_z - initialize localization recursive filter (z direction)
@@ -102,6 +103,10 @@ module hybrid_ensemble_isotropic
use control_vectors, only: cvars2d,cvars3d,nc2d,nc3d
use string_utility, only: StrUpCase
+! For MGBF
+ use mg_intstate
+ use mg_timers
+
implicit none
! set default to private
@@ -174,6 +179,12 @@ module hybrid_ensemble_isotropic
real(r_kind),allocatable,dimension(:,:,:) :: spectral_filter,sqrt_spectral_filter
integer(i_kind),allocatable,dimension(:) :: k_index
+ integer(r_kind) :: nval_loc_en
+
+! For MGBF
+ type (mg_intstate_type), allocatable, dimension(:) :: obj_mgbf
+ real(r_kind), allocatable, dimension(:,:,:) :: work_mgbf
+
! following is for special subdomain to slab variables used when internally generating ensemble members
integer(i_kind) nval2f,nscl
@@ -183,7 +194,6 @@ module hybrid_ensemble_isotropic
logical,parameter:: debug=.false.
-
contains
subroutine init_rf_z(z_len)
@@ -247,7 +257,7 @@ subroutine init_rf_z(z_len)
kap1=rd_over_cp+one
kapr=one/rd_over_cp
nxy=grd_ens%latlon11
- rnsig=float(nsig)
+ rnsig=real(nsig,r_kind)
! use new factorization:
@@ -591,7 +601,7 @@ subroutine new_factorization_rf_x(f,iadvance,iback,nlevs,ig)
ny=grd_loc%nlat ; nx=grd_loc%nlon ; nz=nlevs
if(vvlocal)then
-!$omp parallel do schedule(dynamic,1) private(k,j,i,l)
+!$omp parallel do schedule(static,1) private(k,j,i,l)
do k=1,nz
if(iadvance == 1) then
@@ -634,7 +644,7 @@ subroutine new_factorization_rf_x(f,iadvance,iback,nlevs,ig)
enddo
else
-!$omp parallel do schedule(dynamic,1) private(k,j,i,l)
+!$omp parallel do schedule(static,1) private(k,j,i,l)
do k=1,nz
if(iadvance == 1) then
@@ -1607,7 +1617,7 @@ subroutine fix_belt(z)
real(r_kind) zloc1(ny,nx)
integer(i_kind) i,ii,j,jj,k
-!$omp parallel do schedule(dynamic,1) private(j,k,i,jj,ii,zloc1)
+!$omp parallel do schedule(static,1) private(j,k,i,jj,ii,zloc1)
do j=1,nscl
do k=1,nnnn1o
i=0
@@ -1686,7 +1696,7 @@ subroutine rescale_ensemble_rh_perturbations
end if
do m=1,ntlevs_ens
do ig=1,ntotensgrp
-!$omp parallel do schedule(dynamic,1) private(n,i,j,k,w3,istatus)
+!$omp parallel do schedule(static,1) private(n,i,j,k,w3,istatus)
do n=1,n_ens
call gsi_bundlegetpointer(en_perts(n,ig,m),'q',w3,istatus)
if(istatus/=0) then
@@ -1732,6 +1742,7 @@ subroutine destroy_ensemble
use hybrid_ensemble_parameters, only: l_hyb_ens,n_ens,ntlevs_ens
use hybrid_ensemble_parameters, only: en_perts,ps_bar
use hybrid_ensemble_parameters, only: ntotensgrp
+ use hybrid_ensemble_parameters, only: l_mgbf_loc
implicit none
integer(i_kind) istatus,n,m,ig
@@ -1750,6 +1761,7 @@ subroutine destroy_ensemble
enddo
deallocate(ps_bar)
deallocate(en_perts)
+ if(l_mgbf_loc) call print_mg_timers("mgbf_timing_cpu.csv", print_cpu, mype)
end if
return
@@ -1835,7 +1847,7 @@ subroutine ensemble_forward_model(cvec,a_en,ibin)
ipx=1
-!$omp parallel do schedule(dynamic,1) private(j,n,ic3,k,i,ipic,ig,iaens)
+!$omp parallel do schedule(static,1) private(j,n,ic3,k,i,ipic,ig,iaens)
do k=1,km
do ic3=1,nc3d
ipic=ipc3d(ic3)
@@ -1860,7 +1872,6 @@ subroutine ensemble_forward_model(cvec,a_en,ibin)
enddo
enddo
-!$omp parallel do schedule(dynamic,1) private(j,n,k,i,ic2,ipic,ig,iaens)
do ic2=1,nc2d
ipic=ipc2d(ic2)
do j=1,jm
@@ -1883,8 +1894,8 @@ subroutine ensemble_forward_model(cvec,a_en,ibin)
iaens=ensgrp2aensgrp(ig,ic2+nc3d,ibin)
if(iaens>0) then
do n=1,n_ens
- do j=1,jm
- do k=1,km_tmp
+ do k=1,km_tmp
+ do j=1,jm
do i=1,im
cvec%r2(ipic)%q(i,j)=cvec%r2(ipic)%q(i,j) &
+a_en(iaens,n)%r3(ipx)%q(i,j,k)*en_perts(n,ig,ibin)%r2(ipic)%qr4(i,j)*pwgt(i,j,k)
@@ -2012,7 +2023,7 @@ subroutine ensemble_forward_model_dual_res(cvec,a_en,ibin)
im=work_ens%grid%im
jm=work_ens%grid%jm
km=work_ens%grid%km
-!$omp parallel do schedule(dynamic,1) private(j,n,ic3,k,i,ipic,ig,iaens)
+!$omp parallel do schedule(static,1) private(j,n,ic3,k,i,ipic,ig,iaens)
do k=1,km
do ic3=1,nc3d
ipic=ipc3d(ic3)
@@ -2036,7 +2047,6 @@ subroutine ensemble_forward_model_dual_res(cvec,a_en,ibin)
enddo
enddo
enddo
-!$omp parallel do schedule(dynamic,1) private(j,n,k,i,ic2,ipic,ig,iaens)
do ic2=1,nc2d
ipic=ipc2d(ic2)
do j=1,jm
@@ -2189,7 +2199,7 @@ subroutine ensemble_forward_model_ad(cvec,a_en,ibin)
endif
ipx=1
-!$omp parallel do schedule(dynamic,1) private(j,n,ic3,k,i,ic2,ipic,ig,iaens)
+!$omp parallel do schedule(static,1) private(j,n,ic3,k,i,ic2,ipic,ig,iaens)
do n=1,n_ens
do ig=1,ntotensgrp
do ic3=1,nc3d
@@ -2206,6 +2216,7 @@ subroutine ensemble_forward_model_ad(cvec,a_en,ibin)
enddo
endif ! iaens>0
enddo
+
do ic2=1,nc2d
iaens=ensgrp2aensgrp(ig,ic2+nc3d,ibin)
if(iaens>0) then
@@ -2354,7 +2365,7 @@ subroutine ensemble_forward_model_ad_dual_res(cvec,a_en,ibin)
im=a_en(1,1)%grid%im
jm=a_en(1,1)%grid%jm
km=a_en(1,1)%grid%km
-!$omp parallel do schedule(dynamic,1) private(j,n,ic3,k,i,ic2,ipic,ig,iaens)
+!$omp parallel do schedule(static,1) private(j,n,ic3,k,i,ic2,ipic,ig,iaens)
do n=1,n_ens
do ig=1,ntotensgrp
do ic3=1,nc3d
@@ -2686,7 +2697,7 @@ subroutine sqrt_beta_s_mult_cvec(grady)
endif
! multiply by sqrt_beta_s
-!$omp parallel do schedule(dynamic,1) private(ic3,ic2,k,j,i,ii)
+!$omp parallel do schedule(static,1) private(ic3,ic2,k,j,i,ii)
do j=1,lon2
do ii=1,nsubwin
do ic3=1,nc3d
@@ -2784,7 +2795,7 @@ subroutine sqrt_beta_s_mult_bundle(grady)
endif
! multiply by sqrt_beta_s
-!$omp parallel do schedule(dynamic,1) private(ic3,ic2,k,j,i)
+!$omp parallel do schedule(static,1) private(ic3,ic2,k,j,i)
do j=1,lon2
do ic3=1,nc3d
! check for ozone and skip if oz_univ_static = true
@@ -2864,12 +2875,12 @@ subroutine sqrt_beta_e_mult_cvec(grady)
call timer_ini('sqrt_beta_e_mult')
! multiply by sqrt_beta_e
-!$omp parallel do schedule(dynamic,1) private(nn,k,j,i,ii,ig)
- do j=1,grd_ens%lon2
+!$omp parallel do schedule(static,1) private(nn,k,j,i,ii,ig)
+ do nn=1,n_ens
do ii=1,nsubwin
do ig=1,naensgrp
- do nn=1,n_ens
- do k=1,nsig
+ do k=1,nsig
+ do j=1,grd_ens%lon2
do i=1,grd_ens%lat2
grady%aens(ii,ig,nn)%r3(1)%q(i,j,k) = sqrt_beta_e(k)*grady%aens(ii,ig,nn)%r3(1)%q(i,j,k)
enddo
@@ -2931,11 +2942,11 @@ subroutine sqrt_beta_e_mult_bundle(aens)
call timer_ini('sqrt_beta_e_mult')
! multiply by sqrt_beta_e
-!$omp parallel do schedule(dynamic,1) private(nn,k,j,i,ig)
- do j=1,grd_ens%lon2
+!$omp parallel do schedule(static,1) private(nn,k,j,i,ig)
+ do nn=1,n_ens
do ig=1,naensgrp
- do nn=1,n_ens
- do k=1,nsig
+ do k=1,nsig
+ do j=1,grd_ens%lon2
do i=1,grd_ens%lat2
aens(ig,nn)%r3(1)%q(i,j,k) = sqrt_beta_e(k)*aens(ig,nn)%r3(1)%q(i,j,k)
enddo
@@ -2993,19 +3004,18 @@ subroutine init_sf_xy(jcap_in)
integer(i_kind),intent(in ) :: jcap_in
- integer(i_kind) i,ii,j,k,l,n,jcap,kk,nsigend,ig
- real(r_kind),allocatable::g(:),gsave(:)
+ integer(i_kind) i,ii,j,igg,k,l,n,jcap,kk,nsigend,ig
+ real(r_kind),allocatable::g(:),gtemp(:)
real(r_kind) factor
real(r_kind),allocatable::rkm(:),f(:,:),f0(:,:)
real(r_kind) ftest(grd_loc%nlat,grd_loc%nlon,grd_loc%kbegin_loc:grd_loc%kend_alloc)
real(r_single) out1(grd_ens%nlon,grd_ens%nlat)
- real(r_single),allocatable::pn0_npole(:)
+ real(r_single) pn0_npole
real(r_kind) s_ens_h_min
real(r_kind) rlats_ens_local(grd_ens%nlat)
real(r_kind) rlons_ens_local(grd_ens%nlon)
character(5) mapname
logical make_test_maps
- logical,allocatable,dimension(:)::ksame
integer(i_kind) nord_sploc2ens
integer(i_kind) nlon_sploc0,nlon_sploc,nlat_sploc,num_fields
logical print_verbose
@@ -3157,101 +3167,107 @@ subroutine init_sf_xy(jcap_in)
if(.not.allocated(spectral_filter)) allocate(spectral_filter(naensloc,sp_loc%nc,grd_sploc%nsig))
if(.not.allocated(sqrt_spectral_filter)) allocate(sqrt_spectral_filter(naensloc,sp_loc%nc,grd_sploc%nsig))
- allocate(g(sp_loc%nc),gsave(sp_loc%nc))
- allocate(pn0_npole(0:sp_loc%jcap))
- allocate(ksame(grd_sploc%nsig))
+ allocate(g(sp_loc%nc),gtemp(sp_loc%nc))
do ig=1,naensloc
- ksame=.false.
- do k=2,grd_sploc%nsig
- if(s_ens_hv(k,ig) == s_ens_hv(k-1,ig))ksame(k)=.true.
- enddo
spectral_filter(ig,:,:)=zero
- do k=1,grd_sploc%nsig
- if(ksame(k))then
- spectral_filter(ig,:,k)=spectral_filter(ig,:,k-1)
- else
+ level_loop: do k=1,grd_sploc%nsig
+ do kk=1,k-1
+ if(s_ens_hv(k,ig) == s_ens_hv(kk,ig))then
+ spectral_filter(ig,:,k)=spectral_filter(ig,:,k-1)
+ cycle level_loop
+ end if
+ end do
+ if(ig > 1)then
+ do igg=1,ig-1
+ do kk=1,grd_sploc%nsig
+ if(s_ens_hv(k,ig) == s_ens_hv(kk,igg))then
+ spectral_filter(ig,:,k)=spectral_filter(igg,:,kk)
+ cycle level_loop
+ end if
+ end do
+ end do
+ end if
+
+ do i=1,grd_sploc%nlat
+ f0(i,1)=exp(-half*(rkm(i)/s_ens_hv(k,ig))**2)
+ enddo
+
+
+ do j=2,grd_sploc%nlon
do i=1,grd_sploc%nlat
- f0(i,1)=exp(-half*(rkm(i)/s_ens_hv(k,ig))**2)
+ f0(i,j)=f0(i,1)
enddo
+ end do
- do j=2,grd_sploc%nlon
- do i=1,grd_sploc%nlat
- f0(i,j)=f0(i,1)
- enddo
- enddo
- call general_g2s0(grd_sploc,sp_loc,g,f0)
+ call general_g2s0(grd_sploc,sp_loc,g,f0)
- call general_s2g0(grd_sploc,sp_loc,g,f)
+ call general_s2g0(grd_sploc,sp_loc,g,f)
-! adjust so value at np = 1
- f=f/f(grd_sploc%nlat,1)
- f0=f
- call general_g2s0(grd_sploc,sp_loc,g,f)
- call general_s2g0(grd_sploc,sp_loc,g,f)
- if(mype == 0)then
- nsigend=k
- do kk=k+1,grd_sploc%nsig
- if(s_ens_hv(kk,ig) /= s_ens_hv(k,ig))exit
- nsigend=nsigend+1
- enddo
- write(6,900)k,nsigend,sp_loc%jcap,s_ens_hv(k,ig),maxval(abs(f0-f))
-900 format(' in init_sf_xy, jcap,s_ens_hv(',i5,1x,'-',i5,'), max diff(f0-f)=', &
+! adjust so value at np = 1
+ f=f/f(grd_sploc%nlat,1)
+ f0=f
+ call general_g2s0(grd_sploc,sp_loc,g,f)
+ call general_s2g0(grd_sploc,sp_loc,g,f)
+ if(mype == 0)then
+ nsigend=k
+ do kk=k+1,grd_sploc%nsig
+ if(s_ens_hv(kk,ig) /= s_ens_hv(k,ig))exit
+ nsigend=nsigend+1
+ enddo
+ write(6,900)k,nsigend,sp_loc%jcap,s_ens_hv(k,ig),maxval(abs(f0-f))
+900 format(' in init_sf_xy, jcap,s_ens_hv(',i5,1x,'-',i5,'), max diff(f0-f)=', &
i10,f10.2,e20.10)
- end if
+ end if
-! correct spectrum by dividing by pn0_npole
- gsave=g
+! correct spectrum by dividing by pn0_npole
-! obtain pn0_npole
- do n=0,sp_loc%jcap
- g=zero
- g(2*n+1)=one
- call general_s2g0(grd_sploc,sp_loc,g,f)
- pn0_npole(n)=f(grd_sploc%nlat,1)
- enddo
+! obtain pn0_npole
+!$omp parallel do schedule(static,1) private(n,gtemp,f)
+ do n=0,sp_loc%jcap
+ gtemp=zero
+ gtemp(2*n+1)=one
+ call general_s2g0(grd_sploc,sp_loc,gtemp,f)
+ pn0_npole=f(grd_sploc%nlat,1)
+ g(2*n+1)=g(2*n+1)/pn0_npole
+ enddo
- g=zero
- do n=0,sp_loc%jcap
- g(2*n+1)=gsave(2*n+1)/pn0_npole(n)
- enddo
-! obtain spectral_filter
+! obtain spectral_filter
- ii=0
- do l=0,sp_loc%jcap
- if(ig>naensgrp) then
- factor=one/g(1)
+ ii=0
+ do l=0,sp_loc%jcap
+ if(ig>naensgrp) then
+ factor=one/g(1)
+ else
+ factor=one
+ if(l>0) factor=half
+ end if
+ do n=l,sp_loc%jcap
+ ii=ii+1
+ if(sp_loc%factsml(ii)) then
+ spectral_filter(ig,ii,k)=zero
else
- factor=one
- if(l>0) factor=half
+ spectral_filter(ig,ii,k)=factor*g(2*n+1)
+ end if
+ ii=ii+1
+ if(l == 0 .or. sp_loc%factsml(ii)) then
+ spectral_filter(ig,ii,k)=zero
+ else
+ spectral_filter(ig,ii,k)=factor*g(2*n+1)
end if
- do n=l,sp_loc%jcap
- ii=ii+1
- if(sp_loc%factsml(ii)) then
- spectral_filter(ig,ii,k)=zero
- else
- spectral_filter(ig,ii,k)=factor*g(2*n+1)
- end if
- ii=ii+1
- if(l == 0 .or. sp_loc%factsml(ii)) then
- spectral_filter(ig,ii,k)=zero
- else
- spectral_filter(ig,ii,k)=factor*g(2*n+1)
- end if
- enddo
enddo
- end if
- enddo
+ enddo
+ enddo level_loop
enddo !ig loop
- deallocate(g,gsave,pn0_npole,ksame)
+ deallocate(g,gtemp)
! Compute sqrt(spectral_filter). Ensure spectral_filter >=0 zero
-!$omp parallel do schedule(dynamic,1) private(k,i)
+!$omp parallel do schedule(static,1) private(k,i)
do ig=1,naensloc
do k=1,grd_sploc%nsig
do i=1,sp_loc%nc
- if (spectral_filter(ig,i,k) < zero) spectral_filter(ig,i,k)=zero
+ spectral_filter(ig,i,k) = max(spectral_filter(ig,i,k),zero)
sqrt_spectral_filter(ig,i,k) = sqrt(spectral_filter(ig,i,k))
end do
end do
@@ -3337,13 +3353,14 @@ subroutine sf_xy(ig,f,k_start,k_end)
if(.not.use_localization_grid) then
if(ig>naensgrp) then
+!$omp parallel do schedule(static,1) private(k,g)
do k=k_start,k_end
call general_g2s0(grd_ens,sp_loc,g,f(:,:,k))
g(:)=g(:)*spectral_filter(ig,:,k_index(k))
call general_s2g0(grd_ens,sp_loc,g,f(:,:,k))
enddo
else
-!$omp parallel do schedule(dynamic,1) private(k)
+!$omp parallel do schedule(static,1) private(k)
do k=k_start,k_end
call sfilter(grd_ens,sp_loc,spectral_filter(ig,:,k_index(k)),f(1,1,k))
enddo
@@ -3353,6 +3370,7 @@ subroutine sf_xy(ig,f,k_start,k_end)
vector=.false.
if(ig>naensgrp) then
+!$omp parallel do schedule(static,1) private(k,g,work)
do k=k_start,k_end
call g_agrid2egrid(p_sploc2ens,work,f(:,:,k:k),k,k,vector(k:k))
call general_g2s0(grd_ens,sp_loc,g,f(:,:,k))
@@ -3361,7 +3379,7 @@ subroutine sf_xy(ig,f,k_start,k_end)
call g_egrid2agrid(p_sploc2ens,work,f(:,:,k:k),k,k,vector(k:k))
enddo
else
-!$omp parallel do schedule(dynamic,1) private(k,work)
+!$omp parallel do schedule(static,1) private(k,work)
do k=k_start,k_end
call g_egrid2agrid_ad(p_sploc2ens,work,f(:,:,k:k),k,k,vector(k:k))
call sfilter(grd_ens,sp_loc,spectral_filter(ig,:,k_index(k)),f(1,1,k))
@@ -3421,6 +3439,7 @@ subroutine sqrt_sf_xy(ig,z,f,k_start,k_end)
if(.not.use_localization_grid) then
+!$omp parallel do schedule(static,1) private(k,g)
do k=k_start,k_end
g(:)=z(:,k)*sqrt_spectral_filter(ig,:,k_index(k))
call general_s2g0(grd_ens,sp_loc,g,f(:,:,k))
@@ -3429,6 +3448,7 @@ subroutine sqrt_sf_xy(ig,z,f,k_start,k_end)
else
vector=.false.
+!$omp parallel do schedule(static,1) private(k,g,work)
do k=k_start,k_end
g(:)=z(:,k)*sqrt_spectral_filter(ig,:,k_index(k))
call general_s2g0(grd_sploc,sp_loc,g,work)
@@ -3488,6 +3508,7 @@ subroutine sqrt_sf_xy_ad(ig,z,f,k_start,k_end)
if(.not.use_localization_grid) then
+!$omp parallel do schedule(static,1) private(k,g)
do k=k_start,k_end
call general_s2g0_ad(grd_ens,sp_loc,g,f(:,:,k))
z(:,k)=g(:)*sqrt_spectral_filter(ig,:,k_index(k))
@@ -3496,6 +3517,7 @@ subroutine sqrt_sf_xy_ad(ig,z,f,k_start,k_end)
else
vector=.false.
+!$omp parallel do schedule(static,1) private(k,g,work)
do k=k_start,k_end
call g_egrid2agrid_ad(p_sploc2ens,work,f(:,:,k:k),k,k,vector(k:k))
call general_s2g0_ad(grd_sploc,sp_loc,g,work)
@@ -3592,13 +3614,12 @@ subroutine bkerror_a_en(grady)
!$$$ end documentation block
use kinds, only: r_kind,i_kind
use constants, only: zero
- use gsi_4dvar, only: nsubwin, lsqrtb
+ use gsi_4dvar, only: nsubwin
use control_vectors, only: control_vector
use timermod, only: timer_ini,timer_fnl
use hybrid_ensemble_parameters, only: n_ens
use hybrid_ensemble_parameters, only: naensgrp
use hybrid_ensemble_parameters, only: alphacvarsclgrpmat
- use hybrid_ensemble_parameters, only: nval_lenz_en
use gsi_bundlemod,only: gsi_bundlegetpointer
implicit none
@@ -3608,12 +3629,7 @@ subroutine bkerror_a_en(grady)
! Declare local variables
integer(i_kind) ii,ip,istatus,k,ig,ig2
real(r_kind),allocatable,dimension(:,:) :: z
- real(r_kind),allocatable,dimension(:) :: ztmp
-
- if (lsqrtb) then
- write(6,*)'bkerror_a_en: not for use with lsqrtb'
- call stop2(317)
- end if
+ real(r_kind),allocatable,dimension(:) :: z2
! Initialize timer
call timer_ini('bkerror_a_en')
@@ -3629,33 +3645,29 @@ subroutine bkerror_a_en(grady)
call sqrt_beta_e_mult(grady)
! Apply variances, as well as vertical & horizontal parts of background error
- do ii=1,nsubwin
- if (naensgrp==1) then
+ if (naensgrp==1) then
+ do ii=1,nsubwin
call bkgcov_a_en_new_factorization(1,grady%aens(ii,1,1:n_ens))
- else
- allocate(z(naensgrp,nval_lenz_en))
+ end do
+ else
+ allocate(z(nval_loc_en,naensgrp))
+ allocate(z2(nval_loc_en))
+ do ii=1,nsubwin
do ig=1,naensgrp
- call ckgcov_a_en_new_factorization_ad(ig,z(ig,:),grady%aens(ii,ig,1:n_ens))
+ call ckgcov_a_en_new_factorization_ad(ig,z(1,ig),grady%aens(ii,ig,1:n_ens))
enddo
- allocate(ztmp(naensgrp))
- do k=1,nval_lenz_en
- ztmp=zero
- do ig=1,naensgrp
- do ig2=1,naensgrp
- ztmp(ig) = ztmp(ig) + z(ig2,k) * alphacvarsclgrpmat(ig,ig2)
+ do ig=1,naensgrp
+ z2=zero
+ do ig2=1,naensgrp
+ do k=1,nval_loc_en
+ z2(k) = z2(k) + z(k,ig2) * alphacvarsclgrpmat(ig,ig2)
enddo
enddo
- do ig=1,naensgrp
- z(ig,k) = ztmp(ig)
- enddo
- enddo
- deallocate(ztmp)
- do ig=1,naensgrp
- call ckgcov_a_en_new_factorization(ig,z(ig,:),grady%aens(ii,ig,1:n_ens))
+ call ckgcov_a_en_new_factorization(ig,z2,grady%aens(ii,ig,1:n_ens))
enddo
- deallocate(z)
- endif
- enddo
+ enddo
+ deallocate(z,z2)
+ endif
! multiply by sqrt_beta_e_mult
call sqrt_beta_e_mult(grady)
@@ -3698,9 +3710,11 @@ subroutine bkgcov_a_en_new_factorization(ig,a_en)
use kinds, only: r_kind,i_kind
use gridmod, only: regional
use hybrid_ensemble_parameters, only: n_ens,grd_loc
+ use hybrid_ensemble_parameters, only: l_mgbf_loc,naensgrp
use general_sub2grid_mod, only: general_sub2grid,general_grid2sub
use gsi_bundlemod, only: gsi_bundle
use gsi_bundlemod, only: gsi_bundlegetpointer
+ use constants, only: zero
implicit none
@@ -3710,66 +3724,107 @@ subroutine bkgcov_a_en_new_factorization(ig,a_en)
type(gsi_bundle),intent(inout) :: a_en(n_ens)
! Local Variables
- integer(i_kind) ii,k,iflg,iadvance,iback,is,ie,ipnt,istatus
+ integer(i_kind) ii,k,iadvance,iback,is,ie,ipnt,istatus
real(r_kind) hwork(grd_loc%inner_vars,grd_loc%nlat,grd_loc%nlon,grd_loc%kbegin_loc:grd_loc%kend_alloc)
real(r_kind),allocatable,dimension(:):: a_en_work
- iflg=1
+ ipnt=1
- call gsi_bundlegetpointer(a_en(1),'a_en',ipnt,istatus)
- if(istatus/=0) then
- write(6,*)'bkgcov_a_en_new_factorization: trouble getting pointer to ensemble CV'
- call stop2(999)
- endif
+! MGBF-based localization (now available only in regional=.true.)
+! (Note that MGBF is applied only in ig<=naensgrp
+! because recursive filter is applied for ig>naensgrp
+! to separate scales for scale-dependent localization
+! even in MGBF-based localization)
+ if(l_mgbf_loc.and.ig<=naensgrp) then
+
+! Apply vertical smoother on each ensemble member
+ allocate(work_mgbf(obj_mgbf(1)%km_a_all,obj_mgbf(1)%nm,obj_mgbf(1)%mm))
+ work_mgbf=zero
+ iadvance=1 ; iback=2
+!$omp parallel do schedule(static,1) private(k,ii,is,ie)
+ do k=1,n_ens
+ ii=(k-1)*grd_loc%nsig
+ is=ii+1
+ ie=ii+grd_loc%nsig
+ if(.not.obj_mgbf(1)%l_vertical_filter) call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,1)
+ call map_work_mgbf(a_en(k)%r3(ipnt)%q,work_mgbf(is:ie,:,:),iadvance,1)
+ enddo
+
+! Mapping from analysis grid to filter grid
+ call obj_mgbf(1)%anal_to_filt_allmap(work_mgbf)
+
+! Apply horizontal smoother for number of horizontal scales
+ call obj_mgbf(1)%filtering_procedure(obj_mgbf(1)%mgbf_proc,0)
+
+! Mapping from filter grid to analysis grid
+ call obj_mgbf(1)%filt_to_anal_allmap(work_mgbf)
+
+! Apply vertical smoother on each ensemble member
+ iadvance=2 ; iback=1
+!$omp parallel do schedule(static,1) private(k,ii,is,ie)
+ do k=1,n_ens
+ ii=(k-1)*grd_loc%nsig
+ is=ii+1
+ ie=ii+grd_loc%nsig
+ call map_work_mgbf(a_en(k)%r3(ipnt)%q,work_mgbf(is:ie,:,:),iadvance,1)
+ if(.not.obj_mgbf(1)%l_vertical_filter) call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,1)
+ enddo
+ deallocate(work_mgbf)
+
+! Recursive/Spectral filter-based localization(ig<=naensgrp)
+! or scale-separation(ig>naensgrp)
+ else
! Apply vertical smoother on each ensemble member
! To avoid my having to touch the general sub2grid and grid2sub,
! get copy for ensemble components to work array
- allocate(a_en_work(n_ens*a_en(1)%ndim),stat=istatus)
- if(istatus/=0) then
- write(6,*)'bkgcov_a_en_new_factorization: trouble in alloc(a_en_work)'
- call stop2(999)
- endif
- iadvance=1 ; iback=2
-!$omp parallel do schedule(dynamic,1) private(k,ii,is,ie)
- do k=1,n_ens
- call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,ig)
- ii=(k-1)*a_en(1)%ndim
- is=ii+1
- ie=ii+a_en(1)%ndim
- a_en_work(is:ie)=a_en(k)%values(1:a_en(k)%ndim)
- enddo
+ allocate(a_en_work(n_ens*a_en(1)%ndim),stat=istatus)
+ if(istatus/=0) then
+ write(6,*)'bkgcov_a_en_new_factorization: trouble in alloc(a_en_work)'
+ call stop2(999)
+ endif
+ iadvance=1 ; iback=2
+!$omp parallel do schedule(static,1) private(k,ii,is,ie)
+ do k=1,n_ens
+ call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,ig)
+ ii=(k-1)*a_en(1)%ndim
+ is=ii+1
+ ie=ii+a_en(1)%ndim
+ a_en_work(is:ie)=a_en(k)%values(1:a_en(k)%ndim)
+ enddo
! Convert from subdomain to full horizontal field distributed among processors
- call general_sub2grid(grd_loc,a_en_work,hwork)
+ call general_sub2grid(grd_loc,a_en_work,hwork)
! Apply horizontal smoother for number of horizontal scales
- if(regional) then
- iadvance=1 ; iback=2
- call new_factorization_rf_x(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
- call new_factorization_rf_y(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
- iadvance=2 ; iback=1
- call new_factorization_rf_y(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
- call new_factorization_rf_x(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
- else
- call sf_xy(ig,hwork,grd_loc%kbegin_loc,grd_loc%kend_loc)
- end if
+ if(regional) then
+ iadvance=1 ; iback=2
+ call new_factorization_rf_x(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
+ call new_factorization_rf_y(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
+ iadvance=2 ; iback=1
+ call new_factorization_rf_y(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
+ call new_factorization_rf_x(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
+ else
+ call sf_xy(ig,hwork,grd_loc%kbegin_loc,grd_loc%kend_loc)
+ end if
! Put back onto subdomains
- call general_grid2sub(grd_loc,hwork,a_en_work)
+ call general_grid2sub(grd_loc,hwork,a_en_work)
! Retrieve ensemble components from long vector
! Apply vertical smoother on each ensemble member
- iadvance=2 ; iback=1
-!$omp parallel do schedule(dynamic,1) private(k,ii,is,ie)
- do k=1,n_ens
- ii=(k-1)*a_en(1)%ndim
- is=ii+1
- ie=ii+a_en(1)%ndim
- a_en(k)%values(1:a_en(k)%ndim)=a_en_work(is:ie)
- call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,ig)
- enddo
- deallocate(a_en_work)
+ iadvance=2 ; iback=1
+!$omp parallel do schedule(static,1) private(k,ii,is,ie)
+ do k=1,n_ens
+ ii=(k-1)*a_en(1)%ndim
+ is=ii+1
+ ie=ii+a_en(1)%ndim
+ a_en(k)%values(1:a_en(k)%ndim)=a_en_work(is:ie)
+ call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,ig)
+ enddo
+ deallocate(a_en_work)
+
+ endif
return
end subroutine bkgcov_a_en_new_factorization
@@ -3801,7 +3856,7 @@ subroutine ckgcov_a_en_new_factorization(ig,z,a_en)
use constants, only: zero
use gridmod, only: regional
use hybrid_ensemble_parameters, only: n_ens,grd_loc
- use hybrid_ensemble_parameters, only: nval_lenz_en
+ use hybrid_ensemble_parameters, only: l_mgbf_loc
use general_sub2grid_mod, only: general_grid2sub
use gsi_bundlemod, only: gsi_bundle
use gsi_bundlemod, only: gsi_bundlegetpointer
@@ -3811,17 +3866,23 @@ subroutine ckgcov_a_en_new_factorization(ig,z,a_en)
! Passed Variables
integer(i_kind),intent(in ) :: ig
type(gsi_bundle),intent(inout) :: a_en(n_ens)
- real(r_kind),dimension(nval_lenz_en),intent(in ) :: z
+ real(r_kind),dimension(nval_loc_en),intent(in ) :: z
+!NOTE:
+! nval_loc_en is the number of horizontally-filtered variables in the domain of each processor.
+! In MGBF-based localization, it is horizontally-local and vertically-global as
+! nval_loc_en = nhoriz * obj_mgbf(ig)%km_all
+! and nhoriz = ( obj_mgbf(ig)%im + obj_mgbf(ig)%hx*2 ) * ( obj_mgbf(ig)%jm + obj_mgbf(ig)%hy*2 )
+! In recursive/spectral filter-based localization, it is horizontally-global and vertically-local as
+! nval_loc_en = nhoriz * ( grd_loc%kend_alloc - grd_loc%kbegin_loc + 1 )
+! and nhoriz = grd_loc%nlat * grd_loc%nlon (for regional recursive filter)
+! nhoriz = ( sp_loc%jcap+1 ) * ( sp_loc%jcap+2 ) (for global spectral filter)
+! but internal array hwork always has
+! dimension grd_loc%nlat * grd_loc%nlon * ( grd_loc%kend_alloc - grd_loc%kbegin_loc + 1 )
+! which would be used as nval_loc_en when the recursive filter is used.
! Local Variables
- integer(i_kind) ii,k,iadvance,iback,is,ie,ipnt,istatus
+ integer(i_kind) ii,i,j,k,iadvance,iback,is,ie,ipnt,istatus
real(r_kind) hwork(grd_loc%nlat*grd_loc%nlon*(grd_loc%kend_alloc-grd_loc%kbegin_loc+1))
-!NOTE: nval_lenz_en = nhoriz*(grd_loc%kend_alloc-grd_loc%kbegin_loc+1)
-! and nhoriz = grd_loc%nlat*grd_loc%nlon for regional,
-! nhoriz = (sp_loc%jcap+1)*(sp_loc%jcap+2) for global
-! but internal array hwork always has
-! dimension grd_loc%nlat*grd_loc%nlon*(grd_loc%kend_alloc-grd_loc%kbegin_loc+1)
-! which just happens to match up with nval_lenz_en for regional case, but not global.
real(r_kind),allocatable,dimension(:):: a_en_work
call gsi_bundlegetpointer(a_en(1),'a_en',ipnt,istatus)
@@ -3830,53 +3891,90 @@ subroutine ckgcov_a_en_new_factorization(ig,z,a_en)
call stop2(999)
endif
+! MGBF-based localization (now available only in regional=.true.)
+ if(l_mgbf_loc) then
+
+! Apply horizontal smoother for number of horizontal scales
+ ii=0
+ do k=1,obj_mgbf(ig)%km_all
+ do j=1-obj_mgbf(ig)%hy,obj_mgbf(ig)%jm+obj_mgbf(ig)%hy
+ do i=1-obj_mgbf(ig)%hx,obj_mgbf(ig)%im+obj_mgbf(ig)%hx
+ ii=ii+1
+ obj_mgbf(ig)%VALL(k,i,j)=z(ii)
+ enddo
+ enddo
+ enddo
+ call obj_mgbf(ig)%filtering_procedure(obj_mgbf(ig)%mgbf_proc,1)
+
+! Mapping from filter grid to analysis grid
+ allocate(work_mgbf(obj_mgbf(ig)%km_a_all,obj_mgbf(ig)%nm,obj_mgbf(ig)%mm))
+ work_mgbf=zero
+ call obj_mgbf(ig)%filt_to_anal_allmap(work_mgbf)
- if(grd_loc%kend_loc+1-grd_loc%kbegin_loc==0) then
+! Apply vertical smoother on each ensemble member
+ iadvance=2 ; iback=1
+!$omp parallel do schedule(static,1) private(k,ii,is,ie)
+ do k=1,n_ens
+ ii=(k-1)*grd_loc%nsig
+ is=ii+1
+ ie=ii+grd_loc%nsig
+ call map_work_mgbf(a_en(k)%r3(ipnt)%q,work_mgbf(is:ie,:,:),iadvance,ig)
+ if(.not.obj_mgbf(ig)%l_vertical_filter) call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,ig)
+ enddo
+ deallocate(work_mgbf)
+
+! Recursive/Spectral filter-based localization
+ else
+
+ if(grd_loc%kend_loc+1-grd_loc%kbegin_loc==0) then
! no work to be done on this processor, but hwork still has allocated space, since
! grd_loc%kend_alloc = grd_loc%kbegin_loc in this case, so set to zero.
- hwork=zero
- else
+ hwork=zero
+ else
! Apply horizontal smoother for number of horizontal scales
- if(regional) then
+ if(regional) then
! Make a copy of input variable z to hwork
- hwork=z
- iadvance=2 ; iback=1
- call new_factorization_rf_y(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
- call new_factorization_rf_x(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
- else
+ hwork=z
+ iadvance=2 ; iback=1
+ call new_factorization_rf_y(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
+ call new_factorization_rf_x(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
+ else
#ifdef LATER
- call sqrt_sf_xy(ig,z,hwork,grd_loc%kbegin_loc,grd_loc%kend_loc)
+ call sqrt_sf_xy(ig,z,hwork,grd_loc%kbegin_loc,grd_loc%kend_loc)
#else
- write(6,*) ' problem with ibm compiler with "use hybrid_ensemble_isotropic, only: sqrt_sf_xy"'
+ write(6,*) ' problem with ibm compiler with "use hybrid_ensemble_isotropic, only: sqrt_sf_xy"'
#endif /*LATER*/
+ end if
end if
- end if
! Put back onto subdomains
- allocate(a_en_work(n_ens*a_en(1)%ndim),stat=istatus)
- if(istatus/=0) then
- write(6,*)'ckgcov_a_en_new_factorization: trouble in alloc(a_en_work)'
- call stop2(999)
- endif
- call general_grid2sub(grd_loc,hwork,a_en_work)
+ allocate(a_en_work(n_ens*a_en(1)%ndim),stat=istatus)
+ if(istatus/=0) then
+ write(6,*)'ckgcov_a_en_new_factorization: trouble in alloc(a_en_work)'
+ call stop2(999)
+ endif
+ call general_grid2sub(grd_loc,hwork,a_en_work)
! Retrieve ensemble components from long vector
- ii=0
- do k=1,n_ens
- is=ii+1
- ie=ii+a_en(1)%ndim
- a_en(k)%values(1:a_en(k)%ndim)=a_en_work(is:ie)
- ii=ii+a_en(1)%ndim
- enddo
- deallocate(a_en_work)
+ ii=0
+ do k=1,n_ens
+ is=ii+1
+ ie=ii+a_en(1)%ndim
+ a_en(k)%values(1:a_en(k)%ndim)=a_en_work(is:ie)
+ ii=ii+a_en(1)%ndim
+ enddo
+ deallocate(a_en_work)
! Apply vertical smoother on each ensemble member
- do k=1,n_ens
-
iadvance=2 ; iback=1
- call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,ig)
+!$omp parallel do schedule(static,1) private(k)
+ do k=1,n_ens
- enddo
+ call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,ig)
+
+ enddo
+
+ endif
return
end subroutine ckgcov_a_en_new_factorization
@@ -3913,7 +4011,7 @@ subroutine ckgcov_a_en_new_factorization_ad(ig,z,a_en)
use constants, only: zero
use gridmod, only: regional
use hybrid_ensemble_parameters, only: n_ens,grd_loc
- use hybrid_ensemble_parameters, only: nval_lenz_en
+ use hybrid_ensemble_parameters, only: l_mgbf_loc
use general_sub2grid_mod, only: general_sub2grid
use gsi_bundlemod, only: gsi_bundle
use gsi_bundlemod, only: gsi_bundlegetpointer
@@ -3923,17 +4021,23 @@ subroutine ckgcov_a_en_new_factorization_ad(ig,z,a_en)
! Passed Variables
integer(i_kind),intent(in ) :: ig
type(gsi_bundle),intent(inout) :: a_en(n_ens)
- real(r_kind),dimension(nval_lenz_en),intent(inout) :: z
+ real(r_kind),dimension(nval_loc_en),intent(inout) :: z
+!NOTE:
+! nval_loc_en is the number of horizontally-filtered variables in the domain of each processor.
+! In MGBF-based localization, it is horizontally-local and vertically-global as
+! nval_loc_en = nhoriz * obj_mgbf(ig)%km_all
+! and nhoriz = ( obj_mgbf(ig)%im + obj_mgbf(ig)%hx*2 ) * ( obj_mgbf(ig)%jm + obj_mgbf(ig)%hy*2 )
+! In recursive/spectral filter-based localization, it is horizontally-global and vertically-local as
+! nval_loc_en = nhoriz * ( grd_loc%kend_alloc - grd_loc%kbegin_loc + 1 )
+! and nhoriz = grd_loc%nlat * grd_loc%nlon (for regional recursive filter)
+! nhoriz = ( sp_loc%jcap+1 ) * ( sp_loc%jcap+2 ) (for global spectral filter)
+! but internal array hwork always has
+! dimension grd_loc%nlat * grd_loc%nlon * ( grd_loc%kend_alloc - grd_loc%kbegin_loc + 1 )
+! which would be used as nval_loc_en when the recursive filter is used.
! Local Variables
- integer(i_kind) ii,k,iadvance,iback,is,ie,ipnt,istatus
+ integer(i_kind) ii,i,j,k,iadvance,iback,is,ie,ipnt,istatus
real(r_kind) hwork(grd_loc%nlat*grd_loc%nlon*(grd_loc%kend_alloc-grd_loc%kbegin_loc+1))
-!NOTE: nval_lenz_en = nhoriz*(grd_loc%kend_alloc-grd_loc%kbegin_loc+1)
-! and nhoriz = grd_loc%nlat*grd_loc%nlon for regional,
-! nhoriz = (sp_loc%jcap+1)*(sp_loc%jcap+2) for global
-! but internal array hwork always has
-! dimension grd_loc%nlat*grd_loc%nlon*(grd_loc%kend_alloc-grd_loc%kbegin_loc+1)
-! which just happens to match up with nval_lenz_en for regional case, but not global.
real(r_kind),allocatable,dimension(:):: a_en_work
call gsi_bundlegetpointer(a_en(1),'a_en',ipnt,istatus)
@@ -3942,52 +4046,159 @@ subroutine ckgcov_a_en_new_factorization_ad(ig,z,a_en)
call stop2(999)
endif
+! MGBF-based localization (now available only in regional=.true.)
+ if(l_mgbf_loc) then
+
! Apply vertical smoother on each ensemble member
- do k=1,n_ens
+ allocate(work_mgbf(obj_mgbf(ig)%km_a_all,obj_mgbf(ig)%nm,obj_mgbf(ig)%mm))
+ work_mgbf=zero
+ iadvance=1 ; iback=2
+!$omp parallel do schedule(static,1) private(k,ii,is,ie)
+ do k=1,n_ens
+ ii=(k-1)*grd_loc%nsig
+ is=ii+1
+ ie=ii+grd_loc%nsig
+ if(.not.obj_mgbf(ig)%l_vertical_filter) call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,ig)
+ call map_work_mgbf(a_en(k)%r3(ipnt)%q,work_mgbf(is:ie,:,:),iadvance,ig)
+ enddo
+
+! Mapping from analysis grid to filter grid
+ call obj_mgbf(ig)%anal_to_filt_allmap(work_mgbf)
+ deallocate(work_mgbf)
+! Apply horizontal smoother for number of horizontal scales
+ call obj_mgbf(ig)%filtering_procedure(obj_mgbf(ig)%mgbf_proc,-1)
+ ii=0
+ do k=1,obj_mgbf(ig)%km_all
+ do j=1-obj_mgbf(ig)%hy,obj_mgbf(ig)%jm+obj_mgbf(ig)%hy
+ do i=1-obj_mgbf(ig)%hx,obj_mgbf(ig)%im+obj_mgbf(ig)%hx
+ ii=ii+1
+ z(ii)=obj_mgbf(ig)%VALL(k,i,j)
+ enddo
+ enddo
+ enddo
+
+! Recursive/Spectral filter-based localization
+ else
+
+! Apply vertical smoother on each ensemble member
iadvance=1 ; iback=2
- call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,ig)
-
- enddo
+!$omp parallel do schedule(static,1) private(k)
+ do k=1,n_ens
+
+ call new_factorization_rf_z(a_en(k)%r3(ipnt)%q,iadvance,iback,ig)
+
+ enddo
! To avoid my having to touch the general sub2grid and grid2sub,
! get copy for ensemble components to work array
- allocate(a_en_work(n_ens*a_en(1)%ndim),stat=istatus)
- if(istatus/=0) then
- write(6,*)'ckgcov_a_en_new_factorization_ad: trouble in alloc(a_en_work)'
- call stop2(999)
- endif
- ii=0
- do k=1,n_ens
- is=ii+1
- ie=ii+a_en(1)%ndim
- a_en_work(is:ie)=a_en(k)%values(1:a_en(k)%ndim)
- ii=ii+a_en(1)%ndim
- enddo
+ allocate(a_en_work(n_ens*a_en(1)%ndim),stat=istatus)
+ if(istatus/=0) then
+ write(6,*)'ckgcov_a_en_new_factorization_ad: trouble in alloc(a_en_work)'
+ call stop2(999)
+ endif
+ ii=0
+ do k=1,n_ens
+ is=ii+1
+ ie=ii+a_en(1)%ndim
+ a_en_work(is:ie)=a_en(k)%values(1:a_en(k)%ndim)
+ ii=ii+a_en(1)%ndim
+ enddo
! Convert from subdomain to full horizontal field distributed among processors
- call general_sub2grid(grd_loc,a_en_work,hwork)
- deallocate(a_en_work)
+ call general_sub2grid(grd_loc,a_en_work,hwork)
+ deallocate(a_en_work)
- if(grd_loc%kend_loc+1-grd_loc%kbegin_loc==0) then
+ if(grd_loc%kend_loc+1-grd_loc%kbegin_loc==0) then
! no work to be done on this processor, but z still has allocated space, since
! grd_loc%kend_alloc = grd_loc%kbegin_loc in this case, so set to zero.
- z=zero
- else
-! Apply horizontal smoother for number of horizontal scales
- if(regional) then
- iadvance=1 ; iback=2
- call new_factorization_rf_x(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
- call new_factorization_rf_y(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
- z=hwork
+ z=zero
else
- call sqrt_sf_xy_ad(ig,z,hwork,grd_loc%kbegin_loc,grd_loc%kend_loc)
+! Apply horizontal smoother for number of horizontal scales
+ if(regional) then
+ iadvance=1 ; iback=2
+ call new_factorization_rf_x(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
+ call new_factorization_rf_y(hwork,iadvance,iback,grd_loc%kend_loc+1-grd_loc%kbegin_loc,ig)
+ z=hwork
+ else
+ call sqrt_sf_xy_ad(ig,z,hwork,grd_loc%kbegin_loc,grd_loc%kend_loc)
+ end if
end if
- end if
+
+ endif
return
end subroutine ckgcov_a_en_new_factorization_ad
+subroutine map_work_mgbf(f,g,iadvance,ig)
+!$$$ subprogram documentation block
+! . . .
+! subprogram: map_work_mgbf
+! prgrmmr: yokota org: NCEP/EMC date: 2024-02-20
+!
+! abstract: mapping field for MGBF
+!
+! program history log:
+!
+! input argument list:
+! f - field to be filtered
+! g - field for MGBF
+! iadvance - =1 to map from f to g, =2 to map from g to f
+! ig - number for smoothing scales
+!
+! output argument list:
+! f - field to be filtered
+! g - field for MGBF
+!
+! attributes:
+! language: f90
+! machine: ibm RS/6000 SP
+!
+!$$$ end documentation block
+
+ use constants, only: zero
+ use hybrid_ensemble_parameters, only: grd_loc
+ implicit none
+
+ integer(i_kind),intent(in ) :: iadvance,ig
+ real(r_kind) ,intent(inout) :: f(grd_loc%lat2,grd_loc%lon2,grd_loc%nsig)
+ real(r_kind) ,intent(inout) :: g(grd_loc%nsig,obj_mgbf(ig)%nm,obj_mgbf(ig)%mm)
+
+ real(r_kind) :: work_tmp(grd_loc%lon2,grd_loc%lat2)
+ integer(i_kind) i,j,k
+
+ if(iadvance == 1) then
+ do k=1,grd_loc%nsig
+ do j=1,grd_loc%lat2
+ do i=1,grd_loc%lon2
+ work_tmp(i,j)=f(j,i,k)
+ enddo
+ enddo
+ do j=1,obj_mgbf(ig)%mm
+ do i=1,obj_mgbf(ig)%nm
+ g(k,i,j)=work_tmp(i+1,j+1)
+ enddo
+ enddo
+ enddo
+ elseif(iadvance == 2) then
+ do k=1,grd_loc%nsig
+ work_tmp=zero
+ do j=1,obj_mgbf(ig)%mm
+ do i=1,obj_mgbf(ig)%nm
+ work_tmp(i+1,j+1)=g(k,i,j)
+ enddo
+ enddo
+ do j=1,grd_loc%lat2
+ do i=1,grd_loc%lon2
+ f(j,i,k)=work_tmp(i,j)
+ enddo
+ enddo
+ enddo
+ endif
+ return
+
+end subroutine map_work_mgbf
+
! ------------------------------------------------------------------------------
! ------------------------------------------------------------------------------
@@ -4004,7 +4215,8 @@ subroutine hybens_grid_setup
! 2010-02-20 parrish, adapt for dual resolution
! 2011-01-30 parrish, fix so regional application depends only on parameters regional
! and dual_res. Rename subroutine get_regional_gefs_grid to get_regional_dual_res_grid.
-!
+!
+! 2022-03-01 X.Lu & X.Wang - add vars for hafs dual ens. POC: xuguang.wang@ou.edu
! input argument list:
!
! output argument list:
@@ -4029,6 +4241,9 @@ subroutine hybens_grid_setup
use constants, only: zero,one
use control_vectors, only: cvars3d,nc2d,nc3d
use gridmod, only: region_lat,region_lon,region_dx,region_dy
+ use hybrid_ensemble_parameters, only:nsclgrp,spc_multwgt,spcwgt_params,global_spectral_filter_sd
+ use hybrid_ensemble_parameters, only:regional_ensemble_option
+ use gsi_rfv3io_mod,only:gsi_rfv3io_get_ens_grid_specs
implicit none
@@ -4037,6 +4252,8 @@ subroutine hybens_grid_setup
logical,allocatable::vector(:)
real(r_kind) eps,r_e
real(r_kind) rlon_a(nlon),rlat_a(nlat),rlon_e(nlon),rlat_e(nlat)
+ character(:),allocatable:: fv3_ens_spec_grid_filename
+ integer :: ierr
nord_e2a=4 ! soon, move this to hybrid_ensemble_parameters
@@ -4080,8 +4297,8 @@ subroutine hybens_grid_setup
region_lat_ens=region_lat
end if
end if
- if(mype==0) write(6,*)' dual_res,nlat,nlon,nlat_ens,nlon_ens,r_e,eps=',&
- dual_res,nlat,nlon,nlat_ens,nlon_ens,r_e,eps
+ if(mype==0) write(6,*)' dual_res,nlat,nlon,nlat_ens,nlon_ens,r_e,eps=',&
+ dual_res,nlat,nlon,nlat_ens,nlon_ens,r_e,eps
if(nlon_ens<=0 .or. nlat_ens<=0) then
nlon_ens=nlon ; nlat_ens=nlat
@@ -4123,12 +4340,38 @@ subroutine hybens_grid_setup
else
if(dual_res) then
call get_region_dx_dy_ens(region_dx_ens,region_dy_ens)
+ if(regional_ensemble_option == 5) then
+ fv3_ens_spec_grid_filename="fv3_ens_grid_spec"
+ call gsi_rfv3io_get_ens_grid_specs(fv3_ens_spec_grid_filename,ierr)
+ endif
else
region_dx_ens=region_dx
region_dy_ens=region_dy
end if
end if
+ if(global_spectral_filter_sd .and. nsclgrp > 1)then
+ allocate(spc_multwgt(sp_ens%nc,nsclgrp))
+ allocate(spcwgt_params(4,nsclgrp))
+ spc_multwgt=1.0
+
+ ! The below parameters are used in Huang et al. (2021, MWR)
+ spcwgt_params(1,1)=4000.0_r_kind
+ spcwgt_params(2,1)=100000000.0_r_kind
+ spcwgt_params(3,1)=1.0_r_kind
+ spcwgt_params(4,1)=3000.0_r_kind
+
+ if( nsclgrp >=3 )then
+ spcwgt_params(1,3)=0.0_r_kind
+ spcwgt_params(2,3)=500.0_r_kind
+ spcwgt_params(3,3)=1.0_r_kind
+ spcwgt_params(4,3)=500.0_r_kind
+ end if
+
+ call init_mult_spc_wgts(jcap_ens)
+
+ end if
+
return
end subroutine hybens_grid_setup
@@ -4148,6 +4391,8 @@ subroutine hybens_localization_setup
! 2012-10-16 wu - only call setup_ens_wgt if necessary
! 2014-05-22 wu modification to allow vertically varying localization scales in regional
! 2022-09-15 yokota - add scale/variable/time-dependent localization
+! 2022-12-09 Y. Wang and X. Wang - add a variable-dependent localization option (assign_vdl_nml=.true.),
+! poc: xuguang.wang@ou.edu
!
! input argument list:
!
@@ -4168,9 +4413,12 @@ subroutine hybens_localization_setup
use hybrid_ensemble_parameters, only: readin_beta,beta_s,beta_e,beta_s0,beta_e0,sqrt_beta_s,sqrt_beta_e
use hybrid_ensemble_parameters, only: readin_localization,create_hybens_localization_parameters, &
vvlocal,s_ens_h,s_ens_hv,s_ens_v,s_ens_vv
- use hybrid_ensemble_parameters, only: ntotensgrp,naensgrp,naensloc,ntlevs_ens,nsclgrp
- use hybrid_ensemble_parameters, only: en_perts
+ use hybrid_ensemble_parameters, only: ntotensgrp,naensgrp,naensloc,ntlevs_ens,nsclgrp,assign_vdl_nml
+ use hybrid_ensemble_parameters, only: en_perts,vdl_scale,vloc_varlist,global_spectral_filter_sd
+ use hybrid_ensemble_parameters, only: ngvarloc
+ use hybrid_ensemble_parameters, only: l_mgbf_loc
use gsi_io, only: verbose
+ use string_utility, only: StrLowCase
implicit none
@@ -4183,9 +4431,12 @@ subroutine hybens_localization_setup
real(r_kind),allocatable:: s_ens_h_gu_x(:,:),s_ens_h_gu_y(:,:)
logical :: l_read_success
type(gsi_bundle) :: a_en(n_ens)
+ type(gsi_bundle),allocatable :: en_pertstmp(:,:),en_pertstmp1(:,:)
type(gsi_grid) :: grid_ens
real(r_kind), pointer :: values(:) => NULL()
+ integer(i_kind) :: iscl, iv, smooth_scales_num
character(len=*),parameter::myname_=myname//'*hybens_localization_setup'
+ character(len=40) :: mgbfname='mgbf_locXX.nml'
l_read_success=.false.
print_verbose=.false. .and. mype == 0
@@ -4245,10 +4496,9 @@ subroutine hybens_localization_setup
vvlocal = .true.
nz = msig
kl = grd_loc%kend_alloc-grd_loc%kbegin_loc+1
- if(.not.allocated(s_ens_h_gu_x)) allocate(s_ens_h_gu_x(grd_loc%nsig*n_ens,naensloc))
- if(.not.allocated(s_ens_h_gu_y)) allocate(s_ens_h_gu_y(grd_loc%nsig*n_ens,naensloc))
endif
+
endif ! if ( readin_localization .or. readin_beta )
100 format(I4)
@@ -4276,8 +4526,6 @@ subroutine hybens_localization_setup
if ( .not. readin_localization ) then ! assign all levels to same value, s_ens_h, s_ens_v
nz = 1
kl = 1
- if(.not.allocated(s_ens_h_gu_x)) allocate(s_ens_h_gu_x(1,naensloc))
- if(.not.allocated(s_ens_h_gu_y)) allocate(s_ens_h_gu_y(1,naensloc))
do ig=1,naensloc
s_ens_hv(:,ig) = s_ens_h(ig)
s_ens_vv(:,ig) = s_ens_v(ig)
@@ -4290,29 +4538,46 @@ subroutine hybens_localization_setup
call normal_new_factorization_rf_z
if ( regional ) then ! convert s_ens_h from km to grid units.
- if ( vvlocal ) then
- call convert_km_to_grid_units(s_ens_h_gu_x(1:nz,:),s_ens_h_gu_y(1:nz,:),nz)
- do n=2,n_ens
- nk=(n-1)*nz
- do k=1,nz
- s_ens_h_gu_x(nk+k,:)=s_ens_h_gu_x(k,:)
- s_ens_h_gu_y(nk+k,:)=s_ens_h_gu_y(k,:)
- enddo
+ if ( l_mgbf_loc ) then
+ allocate(obj_mgbf(naensgrp))
+ do ig=1,naensgrp
+ write(mgbfname(9:10),'(i2.2)') ig
+ call obj_mgbf(ig)%mg_initialize(trim(mgbfname))
enddo
- call init_rf_x(s_ens_h_gu_x(grd_loc%kbegin_loc:grd_loc%kend_alloc,:),kl)
- call init_rf_y(s_ens_h_gu_y(grd_loc%kbegin_loc:grd_loc%kend_alloc,:),kl)
- else
- call convert_km_to_grid_units(s_ens_h_gu_x,s_ens_h_gu_y,nz)
- call init_rf_x(s_ens_h_gu_x,kl)
- call init_rf_y(s_ens_h_gu_y,kl)
endif
- call normal_new_factorization_rf_x
- call normal_new_factorization_rf_y
+ ! Even for MGBF-localization, recursive filter is applied for scale-separation
+ ! in scale-dependent localization, so init_rf_[xy] should be called in nsclgrp>1
+ if( .not. l_mgbf_loc .or. nsclgrp > 1 ) then
+ if ( vvlocal ) then
+ allocate(s_ens_h_gu_x(grd_loc%nsig*n_ens,naensloc))
+ allocate(s_ens_h_gu_y(grd_loc%nsig*n_ens,naensloc))
+ call convert_km_to_grid_units(s_ens_h_gu_x(1:nz,:),s_ens_h_gu_y(1:nz,:),nz)
+ do n=2,n_ens
+ nk=(n-1)*nz
+ do k=1,nz
+ s_ens_h_gu_x(nk+k,:)=s_ens_h_gu_x(k,:)
+ s_ens_h_gu_y(nk+k,:)=s_ens_h_gu_y(k,:)
+ enddo
+ enddo
+ call init_rf_x(s_ens_h_gu_x(grd_loc%kbegin_loc:grd_loc%kend_alloc,:),kl)
+ call init_rf_y(s_ens_h_gu_y(grd_loc%kbegin_loc:grd_loc%kend_alloc,:),kl)
+ else
+ allocate(s_ens_h_gu_x(1,naensloc))
+ allocate(s_ens_h_gu_y(1,naensloc))
+ call convert_km_to_grid_units(s_ens_h_gu_x,s_ens_h_gu_y,nz)
+ call init_rf_x(s_ens_h_gu_x,kl)
+ call init_rf_y(s_ens_h_gu_y,kl)
+ endif
+ call normal_new_factorization_rf_x
+ call normal_new_factorization_rf_y
+ deallocate(s_ens_h_gu_x)
+ deallocate(s_ens_h_gu_y)
+ endif
else
call init_sf_xy(jcap_ens)
endif
- if(ntotensgrp>1) then
+ if(ntotensgrp>1 .and. (.not. global_spectral_filter_sd)) then
call gsi_bundlegetpointer(en_perts(1,1,1),cvars3d,ipc3d,istatus)
if(istatus/=0) then
write(6,*) myname_,': cannot find 3d pointers'
@@ -4326,64 +4591,162 @@ subroutine hybens_localization_setup
if(nsclgrp>1) then
call gsi_gridcreate(grid_ens,grd_ens%lat2,grd_ens%lon2,grd_ens%nsig)
allocate(values(grd_ens%latlon11*grd_ens%nsig*n_ens))
- do ig=1,nsclgrp-1
- ii=0
- do n=1,n_ens
- a_en(n)%values => values(ii+1:ii+grd_ens%latlon11*grd_ens%nsig)
- call gsi_bundleset(a_en(n),grid_ens,'Ensemble Bundle',istatus,names3d=(/'a_en'/),bundle_kind=r_kind)
- if (istatus/=0) then
- write(6,*) myname_,': error alloc(ensemble bundle)'
- call stop2(999)
- endif
- ii=ii+grd_ens%latlon11*grd_ens%nsig
- enddo
- do m=1,ntlevs_ens
+ if( .not. assign_vdl_nml )then
+ do ig=1,nsclgrp-1
+ ii=0
do n=1,n_ens
- en_perts(n,ig+1,m)%valuesr4=en_perts(n,ig,m)%valuesr4
+ a_en(n)%values => values(ii+1:ii+grd_ens%latlon11*grd_ens%nsig)
+ call gsi_bundleset(a_en(n),grid_ens,'Ensemble Bundle',istatus,names3d=(/'a_en'/),bundle_kind=r_kind)
+ if (istatus/=0) then
+ write(6,*) myname_,': error alloc(ensemble bundle)'
+ call stop2(999)
+ endif
+ ii=ii+grd_ens%latlon11*grd_ens%nsig
enddo
- do ic3=1,nc3d
- ipic=ipc3d(ic3)
+ do m=1,ntlevs_ens
do n=1,n_ens
- do k=1,grd_ens%nsig
- a_en(n)%r3(1)%q(:,:,k)=en_perts(n,ig,m)%r3(ipic)%qr4(:,:,k)
+ en_perts(n,ig+1,m)%valuesr4=en_perts(n,ig,m)%valuesr4
+ enddo
+ do ic3=1,nc3d
+ ipic=ipc3d(ic3)
+ do n=1,n_ens
+ do k=1,grd_ens%nsig
+ a_en(n)%r3(1)%q(:,:,k)=en_perts(n,ig,m)%r3(ipic)%qr4(:,:,k)
+ enddo
+ enddo
+ call bkgcov_a_en_new_factorization(naensgrp+ig,a_en)
+ do n=1,n_ens
+ do k=1,grd_ens%nsig
+ en_perts(n,ig,m)%r3(ipic)%qr4(:,:,k)=a_en(n)%r3(1)%q(:,:,k)
+ enddo
enddo
enddo
- call bkgcov_a_en_new_factorization(naensgrp+ig,a_en)
- do n=1,n_ens
- do k=1,grd_ens%nsig
- en_perts(n,ig,m)%r3(ipic)%qr4(:,:,k)=a_en(n)%r3(1)%q(:,:,k)
+ do ic2=1,nc2d
+ ipic=ipc2d(ic2)
+ do n=1,n_ens
+ do k=1,grd_ens%nsig
+ a_en(n)%r3(1)%q(:,:,k)=en_perts(n,ig,m)%r2(ipic)%qr4(:,:)
+ enddo
+ enddo
+ call bkgcov_a_en_new_factorization(naensgrp+ig,a_en)
+ do n=1,n_ens
+ en_perts(n,ig,m)%r2(ipic)%qr4(:,:)=a_en(n)%r3(1)%q(:,:,1)
enddo
enddo
- enddo
- do ic2=1,nc2d
- ipic=ipc2d(ic2)
do n=1,n_ens
- do k=1,grd_ens%nsig
- a_en(n)%r3(1)%q(:,:,k)=en_perts(n,ig,m)%r2(ipic)%qr4(:,:)
+ en_perts(n,ig+1,m)%valuesr4=en_perts(n,ig+1,m)%valuesr4-en_perts(n,ig,m)%valuesr4
+ enddo
+ enddo
+ do n=1,n_ens
+ call gsi_bundleunset(a_en(n),istatus)
+ enddo
+ enddo
+ else ! assign_vdl_nml
+ smooth_scales_num = naensloc - naensgrp
+ ngvarloc = 1 ! forced to 1 in this option
+ allocate(en_pertstmp(n_ens,ntlevs_ens))
+ allocate(en_pertstmp1(n_ens,ntlevs_ens))
+ do n = 1, n_ens
+ do m = 1, ntlevs_ens
+ call gsi_bundlecreate(en_pertstmp(n,m),grid_ens,'ensemble2',istatus,names2d=cvars2d,names3d=cvars3d,bundle_kind=r_single)
+ call gsi_bundlecreate(en_pertstmp1(n,m),grid_ens,'ensemble1',istatus,names2d=cvars2d,names3d=cvars3d,bundle_kind=r_single)
+ end do
+ end do
+ ig = 1
+ do iscl=1,smooth_scales_num + 1
+ ii=0
+ do n=1,n_ens
+ a_en(n)%values => values(ii+1:ii+grd_ens%latlon11*grd_ens%nsig)
+ call gsi_bundleset(a_en(n),grid_ens,'Ensemble Bundle',istatus,names3d=(/'a_en'/),bundle_kind=r_kind)
+ if (istatus/=0) then
+ write(6,*) myname_,': error alloc(ensemble bundle)'
+ call stop2(999)
+ endif
+ ii=ii+grd_ens%latlon11*grd_ens%nsig
+ enddo
+
+ do m=1,ntlevs_ens
+ if( ig == 1 )then
+ do n=1,n_ens
+ en_pertstmp(n,m)%valuesr4=en_perts(n,ig,m)%valuesr4
+ enddo
+ end if
+ do ic3=1,nc3d
+ ipic=ipc3d(ic3)
+ do n=1,n_ens
+ do k=1,grd_ens%nsig
+ a_en(n)%r3(1)%q(:,:,k)=en_pertstmp(n,m)%r3(ipic)%qr4(:,:,k)
+ enddo
+ enddo
+ if(iscl <= smooth_scales_num) call bkgcov_a_en_new_factorization(naensgrp+iscl,a_en)
+ do n=1,n_ens
+ do k=1,grd_ens%nsig
+ en_pertstmp1(n,m)%r3(ipic)%qr4(:,:,k)=a_en(n)%r3(1)%q(:,:,k)
+ if( vdl_scale(ig) == 0 )then
+ en_perts(n,ig,m)%r3(ipic)%qr4(:,:,k)=a_en(n)%r3(1)%q(:,:,k)
+ else ! VDL is activated
+ do iv = 1, vdl_scale(ig)
+ en_perts(n,ig+iv-1,m)%r3(ipic)%qr4(:,:,k)=0.0_r_single
+ if( any( trim(StrLowCase(cvars3d(ic3))) == vloc_varlist(ig+iv-1,:) ) ) then
+ en_perts(n,ig+iv-1,m)%r3(ipic)%qr4(:,:,k)=a_en(n)%r3(1)%q(:,:,k)
+ end if
+ end do
+ end if
+ enddo
+ enddo
+ enddo
+ do ic2=1,nc2d
+ ipic=ipc2d(ic2)
+ do n=1,n_ens
+ do k=1,grd_ens%nsig
+ a_en(n)%r3(1)%q(:,:,k)=en_pertstmp(n,m)%r2(ipic)%qr4(:,:)
+ enddo
+ enddo
+ if(iscl <= smooth_scales_num) call bkgcov_a_en_new_factorization(naensgrp+iscl,a_en)
+ do n=1,n_ens
+ en_pertstmp1(n,m)%r2(ipic)%qr4(:,:)=a_en(n)%r3(1)%q(:,:,1)
+ if( vdl_scale(ig) == 0 )then
+ en_perts(n,ig,m)%r2(ipic)%qr4(:,:)=a_en(n)%r3(1)%q(:,:,1)
+ else ! VDL is activated
+ do iv = 1, vdl_scale(ig)
+ en_perts(n,ig+iv-1,m)%r2(ipic)%qr4(:,:)=0.0_r_single
+ if( any( trim(StrLowCase(cvars2d(ic2))) == vloc_varlist(ig+iv-1,:) ) ) then
+ en_perts(n,ig+iv-1,m)%r2(ipic)%qr4(:,:)=a_en(n)%r3(1)%q(:,:,1)
+ end if
+ end do
+ end if
enddo
enddo
- call bkgcov_a_en_new_factorization(naensgrp+ig,a_en)
do n=1,n_ens
- en_perts(n,ig,m)%r2(ipic)%qr4(:,:)=a_en(n)%r3(1)%q(:,:,1)
+ en_pertstmp(n,m)%valuesr4=en_pertstmp(n,m)%valuesr4-en_pertstmp1(n,m)%valuesr4
enddo
enddo
do n=1,n_ens
- en_perts(n,ig+1,m)%valuesr4=en_perts(n,ig+1,m)%valuesr4-en_perts(n,ig,m)%valuesr4
+ call gsi_bundleunset(a_en(n),istatus)
enddo
+ if( vdl_scale(ig) == 0 )then
+ ig = ig + 1
+ else
+ ig = ig + vdl_scale(ig)
+ end if
enddo
do n=1,n_ens
- call gsi_bundleunset(a_en(n),istatus)
- enddo
- enddo
- deallocate(values)
- endif
- do ig=nsclgrp+1,ntotensgrp
- do m=1,ntlevs_ens
- do n=1,n_ens
- en_perts(n,ig,m)%valuesr4=en_perts(n,ig-nsclgrp,m)%valuesr4
- enddo
- enddo
- enddo
+ do m=1,ntlevs_ens
+ call gsi_bundledestroy(en_pertstmp(n,m),istatus)
+ call gsi_bundledestroy(en_pertstmp1(n,m),istatus)
+ end do
+ end do
+ deallocate(en_pertstmp,en_pertstmp1)
+ end if
+ deallocate(values)
+ endif
+ do ig=nsclgrp+1,ntotensgrp
+ do m=1,ntlevs_ens
+ do n=1,n_ens
+ en_perts(n,ig,m)%valuesr4=en_perts(n,ig-nsclgrp,m)%valuesr4
+ enddo
+ enddo
+ enddo
endif
!!!!!!!! setup beta_s, beta_e!!!!!!!!!!!!
@@ -4401,6 +4764,16 @@ subroutine hybens_localization_setup
else
nval_lenz_en = sp_loc%nc*(grd_loc%kend_alloc-grd_loc%kbegin_loc+1)
endif
+ ! nval_loc_en is the number of horizontally-filtered variables in the domain of each processor,
+ ! which is the same as nval_lenz_en (horizontally-global and vertically-local) in recursive/spectral filter
+ ! but horizontally-local and vertically-global in MGBF.
+ if ( l_mgbf_loc ) then
+ nval_loc_en = maxval( obj_mgbf(1:naensgrp)%km_all &
+ & * (obj_mgbf(1:naensgrp)%im + obj_mgbf(1:naensgrp)%hx*2) &
+ & * (obj_mgbf(1:naensgrp)%jm + obj_mgbf(1:naensgrp)%hy*2) )
+ else
+ nval_loc_en = nval_lenz_en
+ endif
! setup vertical weighting for ensemble contribution to psfc
call setup_pwgt
@@ -5314,6 +5687,7 @@ subroutine acceptable_for_essl_fft(nin,nout)
nout=n_acceptable_table(i)
if(nout.ge.nin) exit
enddo
+ deallocate(n_acceptable_table)
return
end subroutine acceptable_for_essl_fft
@@ -5428,7 +5802,7 @@ subroutine setup_ensgrp2aensgrp
!
!$$$ end documentation block
use constants, only: zero,one
- use hybrid_ensemble_parameters, only: l_timloc_opt,i_ensloccov4tim,i_ensloccov4var,i_ensloccov4scl
+ use hybrid_ensemble_parameters, only: l_timloc_opt,r_ensloccov4tim,r_ensloccov4var,r_ensloccov4scl
use hybrid_ensemble_parameters, only: ensloccov4tim,ensloccov4var,ensloccov4scl
use hybrid_ensemble_parameters, only: ntotensgrp,naensgrp,ntlevs_ens,nsclgrp,ngvarloc
use hybrid_ensemble_parameters, only: ensgrp2aensgrp
@@ -5471,33 +5845,12 @@ subroutine setup_ensgrp2aensgrp
enddo
enddo
- if (i_ensloccov4tim==0) then
- ensloccov4tim=one
- elseif (i_ensloccov4tim==1)then
- ensloccov4tim=zero
- ensloccov4tim(1)=one
- else
- write(6,*)'setup_ensgrp2aensgrp: wrong i_ensloccov4tim'
- call stop2(666)
- endif
- if (i_ensloccov4var==0) then
- ensloccov4var=one
- elseif (i_ensloccov4var==1)then
- ensloccov4var=zero
- ensloccov4var(1)=one
- else
- write(6,*)'setup_ensgrp2aensgrp: wrong i_ensloccov4var'
- call stop2(666)
- endif
- if (i_ensloccov4scl==0) then
- ensloccov4scl=one
- elseif (i_ensloccov4scl==1)then
- ensloccov4scl=zero
- ensloccov4scl(1)=one
- else
- write(6,*)'setup_ensgrp2aensgrp: wrong i_ensloccov4scl'
- call stop2(666)
- endif
+ ensloccov4tim=r_ensloccov4tim
+ ensloccov4tim(1)=one
+ ensloccov4var=r_ensloccov4var
+ ensloccov4var(1)=one
+ ensloccov4scl=r_ensloccov4scl
+ ensloccov4scl(1)=one
do itim2=1,ntimloc
do itim1=1,ntimloc
diff --git a/src/gsi/hybrid_ensemble_parameters.f90 b/src/gsi/hybrid_ensemble_parameters.f90
index 7b1c963764..d31eccb7e4 100644
--- a/src/gsi/hybrid_ensemble_parameters.f90
+++ b/src/gsi/hybrid_ensemble_parameters.f90
@@ -128,20 +128,28 @@ module hybrid_ensemble_parameters
! function of z, default = .false.
! ensemble_path: path to ensemble members; default './'
! ens_fast_read: read ensemble in parallel; default '.false.'
+! parallelization_over_ensmembers: parallelly read ensemble members for FV3-LAM; default '.false'
! sst_staticB: if .true. (default) uses only static part of B error covariance for SST
! nsclgrp: number of scale-dependent localization lengths
! l_timloc_opt: if true, then turn on time-dependent localization
! ngvarloc: number of variable-dependent localization lengths
! naensloc: total number of spatial localization lengths and scale separation lengths (should be naensgrp+nsclgrp-1)
-! i_ensloccov4tim: flag of cross-temporal localization
-! =0: cross-temporal covariance is retained
-! =1: cross-temporal covariance is zero
-! i_ensloccov4var: flag of cross-variable localization
-! =0: cross-variable covariance is retained
-! =1: cross-variable covariance is zero
-! i_ensloccov4scl: flag of cross-scale localization
-! =0: cross-scale covariance is retained
-! =1: cross-scale covariance is zero
+! r_ensloccov4tim: factor multiplying to cross-time covariance
+! For example,
+! =0.0: cross-time covariance is decreased to zero
+! =0.5: cross-time covariance is decreased to half
+! =1.0: cross-time covariance is retained
+! r_ensloccov4var: factor multiplying to cross-variable covariance
+! For example,
+! =0.0: cross-variable covariance is decreased to zero
+! =0.5: cross-variable covariance is decreased to half
+! =1.0: cross-variable covariance is retained
+! r_ensloccov4scl: factor multiplying to cross-scale covariance
+! For example,
+! =0.0: cross-scale covariance is decreased to zero
+! =0.5: cross-scale covariance is decreased to half
+! =1.0: cross-scale covariance is retained
+! l_mgbf_loc: if true, multi-grid beta filter is used for localization instead of recursive filter
!=====================================================================================================
!
!
@@ -176,6 +184,7 @@ module hybrid_ensemble_parameters
! 2015-02-11 Hu - add flag l_ens_in_diff_time to force GSI hybrid use ensembles not available at analysis time
! 2015-09-18 todling - add sst_staticB to control use of ensemble SST error covariance
! 2022-09-15 yokota - add scale/variable/time-dependent localization
+! 2024-02-20 yokota - add MGBF-based localization
!
! subroutines included:
@@ -286,6 +295,7 @@ module hybrid_ensemble_parameters
public :: generate_ens,n_ens,nlon_ens,nlat_ens,jcap_ens,jcap_ens_test,l_hyb_ens,&
s_ens_h,oz_univ_static,vvlocal
public :: n_ens_gfs,n_ens_fv3sar
+ public :: weight_ens_gfs,weight_ens_fv3sar
public :: uv_hyb_ens,q_hyb_ens,s_ens_v,beta_s0,beta_e0,aniso_a_en,s_ens_hv,s_ens_vv
public :: readin_beta,beta_s,beta_e
public :: readin_localization
@@ -324,15 +334,24 @@ module hybrid_ensemble_parameters
public :: ensloccov4tim,ensloccov4var,ensloccov4scl
public :: alphacvarsclgrpmat
public :: l_timloc_opt
- public :: i_ensloccov4tim,i_ensloccov4var,i_ensloccov4scl
+ public :: r_ensloccov4tim,r_ensloccov4var,r_ensloccov4scl
+ public :: l_mgbf_loc
public :: idaen3d,idaen2d
public :: ens_fast_read
+ public :: parallelization_over_ensmembers
public :: l_both_fv3sar_gfs_ens
public :: sst_staticB
public :: limqens
+ public :: spc_multwgt
+ public :: spcwgt_params
+ public :: vdl_scale,vloc_varlist
+ public :: global_spectral_filter_sd
+ public :: assign_vdl_nml
+
logical l_hyb_ens,uv_hyb_ens,q_hyb_ens,oz_univ_static,sst_staticB
logical l_timloc_opt
+ logical l_mgbf_loc
logical aniso_a_en
logical full_ensemble,pwgtflg
logical generate_ens
@@ -348,10 +367,12 @@ module hybrid_ensemble_parameters
logical vvlocal
logical l_ens_in_diff_time
logical ens_fast_read
+ logical parallelization_over_ensmembers
logical l_both_fv3sar_gfs_ens
integer(i_kind) i_en_perts_io
integer(i_kind) n_ens,nlon_ens,nlat_ens,jcap_ens,jcap_ens_test
integer(i_kind) n_ens_gfs,n_ens_fv3sar
+ real(r_kind) weight_ens_gfs,weight_ens_fv3sar
real(r_kind) beta_s0,beta_e0,grid_ratio_ens
integer(i_kind),parameter::max_naensloc=20
integer(i_kind),parameter::max_nvars=100
@@ -384,11 +405,18 @@ module hybrid_ensemble_parameters
integer(i_kind) :: ntotensgrp=1
integer(i_kind) :: naensloc=1
integer(i_kind) :: ngvarloc=1
- integer(i_kind) :: i_ensloccov4tim=0
- integer(i_kind) :: i_ensloccov4var=0
- integer(i_kind) :: i_ensloccov4scl=0
+ real(r_kind) :: r_ensloccov4tim
+ real(r_kind) :: r_ensloccov4var
+ real(r_kind) :: r_ensloccov4scl
integer(i_kind),allocatable,dimension(:) :: idaen3d,idaen2d
+ real(r_kind),allocatable,dimension(:,:) :: spc_multwgt
+ real(r_kind),allocatable,dimension(:,:) :: spcwgt_params
+ character(len=3) vloc_varlist(max_naensloc,max_nvars)
+ integer(i_kind) vdl_scale(max_naensloc)
+ logical :: global_spectral_filter_sd
+ logical :: assign_vdl_nml
+
! following is for storage of ensemble perturbations:
! def en_perts - array of ensemble perturbations
@@ -404,6 +432,7 @@ module hybrid_ensemble_parameters
real(r_kind),allocatable:: region_lat_ens(:,:),region_lon_ens(:,:)
real(r_kind),allocatable:: region_dx_ens(:,:),region_dy_ens(:,:)
+
contains
subroutine init_hybrid_ensemble_parameters
@@ -437,6 +466,7 @@ subroutine init_hybrid_ensemble_parameters
l_hyb_ens=.false.
l_timloc_opt=.false.
+ l_mgbf_loc=.false.
full_ensemble=.false.
pwgtflg=.false.
uv_hyb_ens=.false.
@@ -476,10 +506,20 @@ subroutine init_hybrid_ensemble_parameters
i_en_perts_io=0 ! default for en_pert IO. 0 is no IO
ensemble_path = './' ! default for path to ensemble members
ens_fast_read=.false.
+ parallelization_over_ensmembers=.false.
limqens=1.0_r_single ! default for limiting ensemble RH (+/-)
l_both_fv3sar_gfs_ens=.false.
n_ens_gfs=0
n_ens_fv3sar=0
+ weight_ens_gfs=one
+ weight_ens_fv3sar=one
+ r_ensloccov4tim=one
+ r_ensloccov4var=one
+ r_ensloccov4scl=one
+ vdl_scale = 0
+ vloc_varlist = 'aaa'
+ global_spectral_filter_sd=.false.
+ assign_vdl_nml=.false.
end subroutine init_hybrid_ensemble_parameters
diff --git a/src/gsi/intall.f90 b/src/gsi/intall.f90
index 0f8faa89f8..d10eb1e7e5 100644
--- a/src/gsi/intall.f90
+++ b/src/gsi/intall.f90
@@ -184,13 +184,13 @@ subroutine intall(sval,sbias,rval,rbias)
use intjomod, only: intjo
use bias_predictors, only : predictors,assignment(=)
use state_vectors, only: allocate_state,deallocate_state
+ use state_vectors, only: qgpresent,qspresent,qrpresent,qipresent,qlpresent
+ use state_vectors, only: cldchpresent,lcbaspresent,howvpresent,wspd10mpresent,pblhpresent,vispresent,gustpresent
use intjcmod, only: intlimq,intlimg,intlimv,intlimp,intlimw10m,intlimhowv,intlimcldch,&
intliml,intjcpdry1,intjcpdry2,intjcdfi,intlimqc
use timermod, only: timer_ini,timer_fnl
use gsi_bundlemod, only: gsi_bundle
use gsi_bundlemod, only: assignment(=)
- use state_vectors, only: svars2d, svars3d
- use mpeu_util, only: getindex
use guess_grids, only: ntguessig,nfldsig
use mpl_allreducemod, only: mpl_allreduce
@@ -238,11 +238,11 @@ subroutine intall(sval,sbias,rval,rbias)
end if
if (ljclimqc) then
if (.not.ljc4tlevs) then
- if (getindex(svars3d,'ql')>0) call intlimqc(rval(ibin_anl),sval(ibin_anl),ntguessig,'ql')
- if (getindex(svars3d,'qi')>0) call intlimqc(rval(ibin_anl),sval(ibin_anl),ntguessig,'qi')
- if (getindex(svars3d,'qr')>0) call intlimqc(rval(ibin_anl),sval(ibin_anl),ntguessig,'qr')
- if (getindex(svars3d,'qs')>0) call intlimqc(rval(ibin_anl),sval(ibin_anl),ntguessig,'qs')
- if (getindex(svars3d,'qg')>0) call intlimqc(rval(ibin_anl),sval(ibin_anl),ntguessig,'qg')
+ if (qlpresent) call intlimqc(rval(ibin_anl),sval(ibin_anl),ntguessig,'ql')
+ if (qipresent) call intlimqc(rval(ibin_anl),sval(ibin_anl),ntguessig,'qi')
+ if (qrpresent) call intlimqc(rval(ibin_anl),sval(ibin_anl),ntguessig,'qr')
+ if (qspresent) call intlimqc(rval(ibin_anl),sval(ibin_anl),ntguessig,'qs')
+ if (qgpresent) call intlimqc(rval(ibin_anl),sval(ibin_anl),ntguessig,'qg')
else
do ibin=1,nobs_bins
if (nobs_bins /= nfldsig) then
@@ -250,34 +250,34 @@ subroutine intall(sval,sbias,rval,rbias)
else
it=ibin
end if
- if (getindex(svars3d,'ql')>0) call intlimqc(rval(ibin),sval(ibin),it,'ql')
- if (getindex(svars3d,'qi')>0) call intlimqc(rval(ibin),sval(ibin),it,'qi')
- if (getindex(svars3d,'qr')>0) call intlimqc(rval(ibin),sval(ibin),it,'qr')
- if (getindex(svars3d,'qs')>0) call intlimqc(rval(ibin),sval(ibin),it,'qs')
- if (getindex(svars3d,'qg')>0) call intlimqc(rval(ibin),sval(ibin),it,'qg')
+ if (qlpresent) call intlimqc(rval(ibin),sval(ibin),it,'ql')
+ if (qipresent) call intlimqc(rval(ibin),sval(ibin),it,'qi')
+ if (qrpresent) call intlimqc(rval(ibin),sval(ibin),it,'qr')
+ if (qspresent) call intlimqc(rval(ibin),sval(ibin),it,'qs')
+ if (qgpresent) call intlimqc(rval(ibin),sval(ibin),it,'qg')
end do
end if
end if ! ljclimqc
! RHS for gust constraint
- if (getindex(svars2d,'gust')>0)call intlimg(rval(1),sval(1))
+ if (gustpresent)call intlimg(rval(1),sval(1))
! RHS for vis constraint
- if (getindex(svars2d,'vis')>0) call intlimv(rval(1),sval(1))
+ if (vispresent) call intlimv(rval(1),sval(1))
! RHS for pblh constraint
- if (getindex(svars2d,'pblh')>0) call intlimp(rval(1),sval(1))
+ if (pblhpresent) call intlimp(rval(1),sval(1))
! RHS for wspd10m constraint
- if (getindex(svars2d,'wspd10m')>0) call intlimw10m(rval(1),sval(1))
+ if (wspd10mpresent) call intlimw10m(rval(1),sval(1))
! RHS for howv constraint
- if (getindex(svars2d,'howv')>0) call intlimhowv(rval(1),sval(1))
+ if (howvpresent) call intlimhowv(rval(1),sval(1))
! RHS for lcbas constraint
- if (getindex(svars2d,'lcbas')>0) call intliml(rval(1),sval(1))
+ if (lcbaspresent) call intliml(rval(1),sval(1))
! RHS for cldch constraint
- if (getindex(svars2d,'cldch')>0) call intlimcldch(rval(1),sval(1))
+ if (cldchpresent) call intlimcldch(rval(1),sval(1))
end if
@@ -296,7 +296,7 @@ subroutine intall(sval,sbias,rval,rbias)
end if
-! Take care of background error for bias correction terms
+! Sum over all processors for bias correction terms
call mpl_allreduce(nrclen,qpvals=qpred)
@@ -313,6 +313,7 @@ subroutine intall(sval,sbias,rval,rbias)
! RHS for Jc DFI
if (ljcdfi .and. nobs_bins>1) call intjcdfi(rval,sval)
+! Put bias correction terms in correct location
if(nsclen > 0)then
do i=1,nsclen
rbias%predr(i)=qpred(i)
diff --git a/src/gsi/intfed.f90 b/src/gsi/intfed.f90
new file mode 100644
index 0000000000..8cb16eba10
--- /dev/null
+++ b/src/gsi/intfed.f90
@@ -0,0 +1,187 @@
+module intfedmod
+!$$$ module documentation block
+! . . . .
+! module: intfedmod module for intfed and its tangent linear intfed_tl
+! prgmmr:
+!
+! abstract: module for intfed and its tangent linear intfed_tl
+!
+! program history log:
+! 2023-08-24 H. Wang - add tangent linear of fed operator to directly assimilate FED
+!
+! subroutines included:
+! sub intfed_
+!
+! variable definitions:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use m_obsNode, only: obsNode
+use m_fedNode, only: fedNode
+use m_fedNode, only: fedNode_typecast
+use m_fedNode, only: fedNode_nextcast
+use m_obsdiagNode, only: obsdiagNode_set
+implicit none
+
+PRIVATE
+PUBLIC intfed
+
+interface intfed; module procedure &
+ intfed_
+end interface
+
+contains
+
+subroutine intfed_(fedhead,rval,sval)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: intfed apply nonlin qc operator for GLM FED
+!
+! abstract: apply observation operator for radar winds
+! with nonlinear qc operator
+!
+! program history log:
+! 2023-08-24 H.Wang - modified based on intdbz.f90
+! - using tangent linear fed operator
+
+!
+! input argument list:
+! fedhead - obs type pointer to obs structure
+! sfed - current fed solution increment
+!
+! output argument list:
+! rfed - fed results from fed observation operator
+!
+! attributes:
+! language: f90
+! machine: ibm RS/6000 SP
+!
+!$$$
+ use kinds, only: r_kind,i_kind
+ use constants, only: half,one,tiny_r_kind,cg_term,r3600
+ use obsmod, only: lsaveobsens,l_do_adjoint,luse_obsdiag
+ use qcmod, only: nlnqc_iter,varqc_iter
+ use jfunc, only: jiter
+ use gsi_bundlemod, only: gsi_bundle
+ use gsi_bundlemod, only: gsi_bundlegetpointer
+ use gsi_4dvar, only: ladtest_obs
+ use wrf_vars_mod, only : fed_exist
+ implicit none
+
+! Declare passed variables
+ class(obsNode), pointer, intent(in ) :: fedhead
+ type(gsi_bundle), intent(in ) :: sval
+ type(gsi_bundle), intent(inout) :: rval
+
+! Declare local variables
+ integer(i_kind) j1,j2,j3,j4,j5,j6,j7,j8,ier,istatus
+! real(r_kind) penalty
+ real(r_kind) val,w1,w2,w3,w4,w5,w6,w7,w8,valfed
+ real(r_kind) cg_fed,p0,grad,wnotgross,wgross,pg_fed
+ real(r_kind),pointer,dimension(:) :: sfed
+ real(r_kind),pointer,dimension(:) :: rfed
+ type(fedNode), pointer :: fedptr
+
+! If no fed obs type data return
+ if(.not. associated(fedhead))return
+
+! Retrieve pointers
+! Simply return if any pointer not found
+ ier=0
+ if(fed_exist)then
+ call gsi_bundlegetpointer(sval,'fed',sfed,istatus);ier=istatus+ier
+ call gsi_bundlegetpointer(rval,'fed',rfed,istatus);ier=istatus+ier
+ else
+ return
+ end if
+
+ if(ier/=0)return
+
+
+ fedptr => fedNode_typecast(fedhead)
+ do while (associated(fedptr))
+ j1=fedptr%ij(1)
+ j2=fedptr%ij(2)
+ j3=fedptr%ij(3)
+ j4=fedptr%ij(4)
+ j5=fedptr%ij(5)
+ j6=fedptr%ij(6)
+ j7=fedptr%ij(7)
+ j8=fedptr%ij(8)
+ w1=fedptr%wij(1)
+ w2=fedptr%wij(2)
+ w3=fedptr%wij(3)
+ w4=fedptr%wij(4)
+ w5=fedptr%wij(5)
+ w6=fedptr%wij(6)
+ w7=fedptr%wij(7)
+ w8=fedptr%wij(8)
+
+
+! Forward model
+ if( fed_exist )then
+ val = w1* sfed(j1)+w2* sfed(j2)+w3* sfed(j3)+w4* sfed(j4)+ &
+ w5* sfed(j5)+w6* sfed(j6)+w7* sfed(j7)+w8* sfed(j8)
+ end if
+
+ if(luse_obsdiag)then
+ if (lsaveobsens) then
+ grad = val*fedptr%raterr2*fedptr%err2
+ !-- fedptr%diags%obssen(jiter) = grad
+ call obsdiagNode_set(fedptr%diags,jiter=jiter,obssen=grad)
+
+ else
+ !-- if (fedptr%luse) fedptr%diags%tldepart(jiter)=val
+ if (fedptr%luse) call obsdiagNode_set(fedptr%diags,jiter=jiter,tldepart=val)
+ endif
+ endif
+
+ if (l_do_adjoint) then
+ if (.not. lsaveobsens) then
+ if( .not. ladtest_obs ) val=val-fedptr%res
+
+! gradient of nonlinear operator
+ if (nlnqc_iter .and. fedptr%pg > tiny_r_kind .and. &
+ fedptr%b > tiny_r_kind) then
+ pg_fed=fedptr%pg*varqc_iter
+ cg_fed=cg_term/fedptr%b
+ wnotgross= one-pg_fed
+ wgross = pg_fed*cg_fed/wnotgross
+ p0 = wgross/(wgross+exp(-half*fedptr%err2*val**2))
+ val = val*(one-p0)
+ endif
+
+ if( ladtest_obs) then
+ grad = val
+ else
+ grad = val*fedptr%raterr2*fedptr%err2
+ end if
+
+ endif
+
+! Adjoint
+ if(fed_exist)then
+ valfed = grad
+ rfed(j1)=rfed(j1)+w1*valfed
+ rfed(j2)=rfed(j2)+w2*valfed
+ rfed(j3)=rfed(j3)+w3*valfed
+ rfed(j4)=rfed(j4)+w4*valfed
+ rfed(j5)=rfed(j5)+w5*valfed
+ rfed(j6)=rfed(j6)+w6*valfed
+ rfed(j7)=rfed(j7)+w7*valfed
+ rfed(j8)=rfed(j8)+w8*valfed
+ end if
+
+ endif
+
+ !fedptr => fedptr%llpoint
+ fedptr => fedNode_nextcast(fedptr)
+ end do
+ return
+end subroutine intfed_
+
+end module intfedmod
diff --git a/src/gsi/intgps.f90 b/src/gsi/intgps.f90
index bc78db085e..16ead93d1c 100644
--- a/src/gsi/intgps.f90
+++ b/src/gsi/intgps.f90
@@ -118,6 +118,7 @@ subroutine intgps_(gpshead,rval,sval)
real(r_kind) :: w1,w2,w3,w4
real(r_kind) :: p_TL,p_AD,t_TL,t_AD,q_TL,q_AD
real(r_kind) :: val,pg_gps
+ real(r_kind),dimension(nsig) :: valk
real(r_kind) ::cg_gps,grad,p0,wnotgross,wgross
real(r_kind),pointer,dimension(:) :: st,sq
real(r_kind),pointer,dimension(:) :: rt,rq
@@ -154,16 +155,19 @@ subroutine intgps_(gpshead,rval,sval)
w3=gpsptr%wij(3)
w4=gpsptr%wij(4)
-
- val=zero
-
! local refractivity (linear operator)
+!$omp parallel do schedule(dynamic,1) private(j,t_TL,q_TL,p_TL)
+ do j=1,nsig
+ t_TL=w1*st(i1(j))+w2*st(i2(j))+w3*st(i3(j))+w4*st(i4(j))
+ q_TL=w1*sq(i1(j))+w2*sq(i2(j))+w3*sq(i3(j))+w4*sq(i4(j))
+ p_TL=w1*sp(i1(j))+w2*sp(i2(j))+w3*sp(i3(j))+w4*sp(i4(j))
+ valk(j) = p_TL*gpsptr%jac_p(j) + t_TL*gpsptr%jac_t(j)+q_TL*gpsptr%jac_q(j)
+ end do
+
+ val=zero
do j=1,nsig
- t_TL=w1* st(i1(j))+w2* st(i2(j))+w3* st(i3(j))+w4* st(i4(j))
- q_TL=w1* sq(i1(j))+w2* sq(i2(j))+w3* sq(i3(j))+w4* sq(i4(j))
- p_TL=w1* sp(i1(j))+w2* sp(i2(j))+w3* sp(i3(j))+w4* sp(i4(j))
- val = val + p_TL*gpsptr%jac_p(j) + t_TL*gpsptr%jac_t(j)+q_TL*gpsptr%jac_q(j)
+ val = val+valk(j)
end do
if (luse_obsdiag)then
@@ -204,6 +208,7 @@ subroutine intgps_(gpshead,rval,sval)
! adjoint
+!$omp parallel do schedule(dynamic,1) private(j,t_AD,q_AD,p_AD)
do j=1,nsig
t_AD = grad*gpsptr%jac_t(j)
rt(i1(j))=rt(i1(j))+w1*t_AD
diff --git a/src/gsi/intjcmod.f90 b/src/gsi/intjcmod.f90
index c0c23151ee..a3af642111 100644
--- a/src/gsi/intjcmod.f90
+++ b/src/gsi/intjcmod.f90
@@ -103,7 +103,7 @@ subroutine intlimq(rval,sval,itbin)
call gsi_bundlegetpointer(gsi_metguess_bundle(itbin),'q',ges_q_it,ier)
if(ier/=0)return
-!$omp parallel do schedule(dynamic,1) private(k,j,i,q)
+!$omp parallel do schedule(dynamic,1) private(k,j,i,ii,q)
do k = 1,nsig
do j = 2,lon1+1
do i = 2,lat1+1
@@ -180,34 +180,30 @@ subroutine intlimqc(rval,sval,itbin,cldtype)
call gsi_bundlegetpointer(sval,'ql',sqc,istatus);ier=istatus+ier
call gsi_bundlegetpointer(rval,'ql',rqc,istatus);ier=istatus+ier
call gsi_bundlegetpointer(gsi_metguess_bundle(itbin),'ql',ges_qc_it,ier1)
- endif
- if (trim(cldtype) == 'qi') then
+ else if (trim(cldtype) == 'qi') then
factqc = factqi
call gsi_bundlegetpointer(sval,'qi',sqc,istatus);ier=istatus+ier
call gsi_bundlegetpointer(rval,'qi',rqc,istatus);ier=istatus+ier
call gsi_bundlegetpointer(gsi_metguess_bundle(itbin),'qi',ges_qc_it,ier1)
- endif
- if (trim(cldtype) == 'qr') then
+ else if (trim(cldtype) == 'qr') then
factqc = factqr
call gsi_bundlegetpointer(sval,'qr',sqc,istatus);ier=istatus+ier
call gsi_bundlegetpointer(rval,'qr',rqc,istatus);ier=istatus+ier
call gsi_bundlegetpointer(gsi_metguess_bundle(itbin),'qr',ges_qc_it,ier1)
- endif
- if (trim(cldtype) == 'qs') then
+ else if (trim(cldtype) == 'qs') then
factqc = factqs
call gsi_bundlegetpointer(sval,'qs',sqc,istatus);ier=istatus+ier
call gsi_bundlegetpointer(rval,'qs',rqc,istatus);ier=istatus+ier
call gsi_bundlegetpointer(gsi_metguess_bundle(itbin),'qs',ges_qc_it,ier1)
- endif
- if (trim(cldtype) == 'qg') then
+ else if (trim(cldtype) == 'qg') then
factqc = factqg
call gsi_bundlegetpointer(sval,'qg',sqc,istatus);ier=istatus+ier
call gsi_bundlegetpointer(rval,'qg',rqc,istatus);ier=istatus+ier
call gsi_bundlegetpointer(gsi_metguess_bundle(itbin),'qg',ges_qc_it,ier1)
endif
- if (mype==0) write(6,*) 'intlimqc: factqc = ', factqc
- if (mype==0) write(6,*) 'intlimqc: ier ier1= ', ier, ier1
if (factqc == zero) return
+ if (mype==0) write(6,*) 'intlimqc: factqc = ', factqc, trim(cldtype)
+ if (mype==0) write(6,*) 'intlimqc: ier ier1= ', ier, ier1
if (ier/=0 .or. ier1/=0) return
!$omp parallel do schedule(dynamic,1) private(k,j,i,qc)
@@ -740,7 +736,7 @@ subroutine intjcpdry(rval,sval,nbins,pjc)
it=ntguessig
mass=zero_quad
- rcon=one_quad/(two_quad*float(nlon))
+ rcon=(one_quad/(two_quad*real(nlon,r_quad)))**2
mm1=mype+1
do n=1,nbins
@@ -805,8 +801,7 @@ subroutine intjcpdry(rval,sval,nbins,pjc)
! Remove water-vapor contribution to get incremental dry ps
! if (mype==0) write(6,*)'intjcpdry: total mass =', mass(n)
! if (mype==0) write(6,*)'intjcpdry: wv mass =', mass(nbins+n)
- dmass=mass(n)-mass(nbins+n)
- dmass=bamp_jcpdry*dmass*rcon*rcon
+ dmass=bamp_jcpdry*(mass(n)-mass(nbins+n))*rcon
if(present(pjc)) then
pjc = dmass*dmass
endif
@@ -872,7 +867,7 @@ subroutine intjcpdry1(sval,nbins,mass)
!
!$$$
use mpimod, only: mype
- use gridmod, only: lat2,lon2,nsig,wgtlats,nlon,istart
+ use gridmod, only: lat2,lon2,nsig,wgtlats,istart
use guess_grids, only: ges_prsi,ntguessig
use gsi_metguess_mod, only: gsi_metguess_get
implicit none
@@ -884,7 +879,7 @@ subroutine intjcpdry1(sval,nbins,mass)
! Declare local variables
real(r_quad),dimension(nsig) :: mass2
- real(r_quad) rcon,con
+ real(r_quad) con
integer(i_kind) i,j,k,it,ii,mm1,icw,iql,iqi
integer(i_kind) iq,iqr,iqs,iqg,iqh,ips
real(r_kind),pointer,dimension(:,:,:) :: sq =>NULL()
@@ -901,13 +896,11 @@ subroutine intjcpdry1(sval,nbins,mass)
it=ntguessig
mass=zero_quad
- rcon=one_quad/(two_quad*float(nlon))
mm1=mype+1
do n=1,nbins
! Retrieve pointers
! Simply return if any pointer not found
- iq=0; icw=0; iql=0; iqi=0; iqr=0; iqs=0; iqg=0; iqh=0
call gsi_bundlegetpointer(sval(n),'q' ,sq, iq )
call gsi_bundlegetpointer(sval(n),'cw',sc, icw )
call gsi_bundlegetpointer(sval(n),'ql',sql, iql )
@@ -1023,11 +1016,10 @@ subroutine intjcpdry2(rval,nbins,mass,pjc)
integer(i_kind) :: n
it=ntguessig
- rcon=one_quad/(two_quad*float(nlon))
+ rcon=(one_quad/(two_quad*real(nlon,r_quad)))**2
mm1=mype+1
do n=1,nbins
- iq=0; icw=0; iql=0; iqi=0; iqr=0; iqs=0; iqg=0; iqh=0
call gsi_bundlegetpointer(rval(n),'q' ,rq, iq )
call gsi_bundlegetpointer(rval(n),'cw',rc, icw )
call gsi_bundlegetpointer(rval(n),'ql',rql, iql )
@@ -1037,7 +1029,7 @@ subroutine intjcpdry2(rval,nbins,mass,pjc)
call gsi_bundlegetpointer(rval(n),'qg',rqg, iqg )
call gsi_bundlegetpointer(rval(n),'qh',rqh, iqh )
call gsi_bundlegetpointer(rval(n),'ps',rp, ips )
- if( iq*ips /=0 .or. icw*(iql+iqi) /=0 ) then
+ if( ips /= 0 .or. iq /=0 .or. icw*(iql+iqi) /=0 ) then
if (mype==0) write(6,*)'intjcpdry2: warning - missing some required variables'
if (mype==0) write(6,*)'intjcpdry2: constraint for dry mass constraint not performed'
return
@@ -1045,8 +1037,7 @@ subroutine intjcpdry2(rval,nbins,mass,pjc)
! Remove water-vapor contribution to get incremental dry ps
! if (mype==0) write(6,*)'intjcpdry: total mass =', mass(n)
! if (mype==0) write(6,*)'intjcpdry: wv mass =', mass(nbins+n)
- dmass=mass(n)-mass(nbins+n)
- dmass=bamp_jcpdry*dmass*rcon*rcon
+ dmass=bamp_jcpdry*(mass(n)-mass(nbins+n))*rcon
if(present(pjc)) then
pjc = dmass*dmass
endif
diff --git a/src/gsi/intjo.f90 b/src/gsi/intjo.f90
index e514a38a22..a68355471b 100644
--- a/src/gsi/intjo.f90
+++ b/src/gsi/intjo.f90
@@ -31,7 +31,7 @@ module intjomod
use gsi_obOperTypeManager, only: &
iobOper_t, iobOper_pw, iobOper_q, &
iobOper_cldtot, iobOper_w, iobOper_dw, &
- iobOper_rw, iobOper_dbz, &
+ iobOper_rw, iobOper_dbz, iobOper_fed, &
iobOper_spd, iobOper_oz, iobOper_o3l, iobOper_colvk, &
iobOper_pm2_5, iobOper_pm10, iobOper_ps, iobOper_tcp, iobOper_sst, &
iobOper_gpsbend, iobOper_gpsref, &
@@ -60,7 +60,7 @@ module intjomod
integer(i_kind),parameter,dimension(obOper_count):: ix_obtype = (/ &
iobOper_t, iobOper_pw, iobOper_q, &
iobOper_cldtot, iobOper_w, iobOper_dw, &
- iobOper_rw, iobOper_dbz, &
+ iobOper_rw, iobOper_dbz, iobOper_fed, &
iobOper_spd, iobOper_oz, iobOper_o3l, iobOper_colvk, &
iobOper_pm2_5, iobOper_pm10, iobOper_ps, iobOper_tcp, iobOper_sst, &
iobOper_gpsbend, iobOper_gpsref, &
@@ -240,8 +240,6 @@ subroutine intjo_(rval,qpred,sval,sbias)
use m_obsdiags, only: obOper_destroy
use gsi_obOper, only: obOper
-use intradmod, only: setrad
-
implicit none
! Declare passed variables
@@ -257,7 +255,6 @@ subroutine intjo_(rval,qpred,sval,sbias)
class(obOper),pointer:: it_obOper
!******************************************************************************
- call setrad(sval(1))
! "RHS for jo", as it was labeled in intall().
!$omp parallel do schedule(dynamic,1) private(ibin,it,ix,it_obOper)
diff --git a/src/gsi/intrad.f90 b/src/gsi/intrad.f90
index 689b6c821e..b062ec953a 100644
--- a/src/gsi/intrad.f90
+++ b/src/gsi/intrad.f90
@@ -83,13 +83,14 @@ subroutine setrad(sval)
use gsi_bundlemod, only: gsi_bundlegetpointer
use gsi_metguess_mod, only: gsi_metguess_get
use mpeu_util, only: getindex
+ use mpimod, only: mype
implicit none
! Declare passed variables
type(gsi_bundle), intent(in ) :: sval
! Declare local variables
- integer(i_kind) ier,istatus,indx
+ integer(i_kind) indx
logical look
real(r_kind),pointer,dimension(:) :: st,sq,scw,soz,su,sv,sqg,sqh,sqi,sql,sqr,sqs
@@ -97,91 +98,110 @@ subroutine setrad(sval)
if(done_setting) return
-! Retrieve pointers; return when not found (except in case of non-essentials)
- ier=0; itsen=0; iqv=0; ius=0; ivs=0; isst=0; ioz=0; icw=0
- iqg=0; iqh=0; iqi=0; iql=0; iqr=0; iqs=0
- call gsi_bundlegetpointer(sval,'u', su, istatus);ius=istatus+ius
- call gsi_bundlegetpointer(sval,'v', sv, istatus);ivs=istatus+ivs
- call gsi_bundlegetpointer(sval,'tsen' ,st, istatus);itsen=istatus+itsen
- call gsi_bundlegetpointer(sval,'q', sq, istatus);iqv=istatus+iqv
- call gsi_bundlegetpointer(sval,'cw' ,scw,istatus);icw=istatus+icw
- call gsi_bundlegetpointer(sval,'oz' ,soz,istatus);ioz=istatus+ioz
- call gsi_bundlegetpointer(sval,'sst',sst,istatus);isst=istatus+isst
- call gsi_bundlegetpointer(sval,'qg' ,sqg,istatus);iqg=istatus+iqg
- call gsi_bundlegetpointer(sval,'qh' ,sqh,istatus);iqh=istatus+iqh
- call gsi_bundlegetpointer(sval,'qi' ,sqi,istatus);iqi=istatus+iqi
- call gsi_bundlegetpointer(sval,'ql' ,sql,istatus);iql=istatus+iql
- call gsi_bundlegetpointer(sval,'qr' ,sqr,istatus);iqr=istatus+iqr
- call gsi_bundlegetpointer(sval,'qs' ,sqs,istatus);iqs=istatus+iqs
- lgoback=(ius/=0).and.(ivs/=0).and.(itsen/=0).and.(iqv/=0).and.(ioz/=0).and.(icw/=0).and.(isst/=0)
- lgoback=lgoback .and.(iqg/=0).and.(iqh/=0).and.(iqi/=0).and.(iql/=0).and.(iqr/=0).and.(iqs/=0)
- if(lgoback)return
-
! check to see if variable participates in forward operator
! tsen
indx=getindex(radjacnames,'tsen')
- look=(itsen==0.and.indx>0)
itsen=-1
- if(look) itsen=radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'tsen',st, itsen)
+ look=itsen==0
+ if(look) itsen=radjacindxs(indx)
+ end if
! q
indx=getindex(radjacnames,'q')
- look=(iqv==0.and.indx>0)
iqv=-1
- if(look) iqv=radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'q', sq, iqv)
+ look=iqv==0
+ if(look) iqv=radjacindxs(indx)
+ end if
! oz
indx=getindex(radjacnames,'oz')
- look=(ioz ==0.and.indx>0)
ioz=-1
- if(look) ioz =radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'oz' , soz,ioz)
+ look=ioz ==0
+ if(look) ioz =radjacindxs(indx)
+ end if
! cw
indx=getindex(radjacnames,'cw')
- look=(icw ==0.and.indx>0)
icw=-1
- if(look) icw =radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'cw' , scw,icw)
+ look=icw ==0
+ if(look) icw =radjacindxs(indx)
+ end if
! sst
indx=getindex(radjacnames,'sst')
- look=(isst==0.and.indx>0)
isst=-1
- if(look) isst=radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'sst', sst,isst)
+ look=isst==0
+ if(look) isst=radjacindxs(indx)
+ end if
! us & vs
indx=getindex(radjacnames,'u')
- look=(ius==0.and.indx>0)
ius=-1
- if(look) ius=radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'u', su, ius)
+ look=ius==0
+ if(look) ius=radjacindxs(indx)
+ end if
indx=getindex(radjacnames,'v')
- look=(ivs==0.and.indx>0)
ivs=-1
- if(look) ivs=radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'v', sv, ivs)
+ look=ivs==0
+ if(look) ivs=radjacindxs(indx)
+ end if
! qg
indx=getindex(radjacnames,'qg')
- look=(iqg ==0.and.indx>0)
iqg=-1
- if(look) iqg =radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'qg' , sqg,iqg)
+ look=iqg ==0
+ if(look) iqg =radjacindxs(indx)
+ end if
! qh
indx=getindex(radjacnames,'qh')
- look=(iqh ==0.and.indx>0)
iqh=-1
- if(look) iqh =radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'qh' , sqh,iqh)
+ look=iqh ==0
+ if(look) iqh =radjacindxs(indx)
+ end if
! qi
indx=getindex(radjacnames,'qi')
- look=(iqi ==0.and.indx>0)
iqi=-1
- if(look) iqi =radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'qi' , sqi,iqi)
+ look=iqi ==0
+ if(look) iqi =radjacindxs(indx)
+ end if
! ql
indx=getindex(radjacnames,'ql')
- look=(iql ==0.and.indx>0)
iql=-1
- if(look) iql =radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'ql' , sql,iql)
+ look=iql ==0
+ if(look) iql =radjacindxs(indx)
+ end if
! qr
indx=getindex(radjacnames,'qr')
- look=(iqr ==0.and.indx>0)
iqr=-1
- if(look) iqr =radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'qr' , sqr,iqr)
+ look=iqr ==0
+ if(look) iqr =radjacindxs(indx)
+ end if
! qs
indx=getindex(radjacnames,'qs')
- look=(iqs ==0.and.indx>0)
iqs=-1
- if(look) iqs =radjacindxs(indx)
+ if(indx > 0)then
+ call gsi_bundlegetpointer(sval,'qs' , sqs,iqs)
+ look=iqs ==0
+ if(look) iqs =radjacindxs(indx)
+ end if
luseu=ius>=0
lusev=ivs>=0
@@ -196,6 +216,26 @@ subroutine setrad(sval)
luseqr=iqr>=0
luseqs=iqs>=0
lusesst=isst>=0
+ lgoback=.not.(luseu .or. lusev .or. luset .or. luseq .or. luseoz .or. lusecw .or. &
+ luseql .or. luseqi .or. luseqh .or. luseqg .or. luseqr .or. luseqs .or. &
+ lusesst)
+
+ if(mype == 0)then
+ write(6,*) ' following variables are used in int and stp radiance calculations '
+ if(luset) write(6,*)'tsen'
+ if(luseq) write(6,*)'q'
+ if(luseoz)write(6,*)'oz'
+ if(luseu) write(6,*)'u'
+ if(lusev) write(6,*)'v'
+ if(lusesst) write(6,*)'sst'
+ if(lusecw) write(6,*)'cw'
+ if(luseql) write(6,*)'ql'
+ if(luseqi) write(6,*)'qi'
+ if(luseqh) write(6,*)'qh'
+ if(luseqg) write(6,*)'qg'
+ if(luseqr) write(6,*)'qr'
+ if(luseqs) write(6,*)'qs'
+ end if
done_setting = .true.
@@ -308,7 +348,7 @@ subroutine intrad_(radhead,rval,sval,rpred,spred)
! Declare local variables
integer(i_kind) i1,i2,i3,i4,n,k,ic,ix,nn,mm,ncr1,ncr2
- integer(i_kind) ier,istatus
+ integer(i_kind) istatus
integer(i_kind),dimension(nsig) :: i1n,i2n,i3n,i4n
real(r_kind),allocatable,dimension(:):: val
real(r_kind) w1,w2,w3,w4
@@ -331,7 +371,6 @@ subroutine intrad_(radhead,rval,sval,rpred,spred)
call timer_ini('intrad')
! Retrieve pointers; return when not found (except in case of non-essentials)
- ier=0
if(luseu)then
call gsi_bundlegetpointer(sval,'u', su, istatus)
call gsi_bundlegetpointer(rval,'u', ru, istatus)
@@ -405,7 +444,8 @@ subroutine intrad_(radhead,rval,sval,rpred,spred)
i4n(k) = i4n(k-1)+latlon11
enddo
-!$omp parallel do schedule(dynamic,1) private(k,i1,i2,i3,i4,mm)
+ tdir=zero
+!$omp parallel do schedule(dynamic,1) private(k,i1,i2,i3,i4)
do k=1,nsig
i1 = i1n(k)
i2 = i2n(k)
@@ -468,7 +508,6 @@ subroutine intrad_(radhead,rval,sval,rpred,spred)
end do
-
! For all other configurations
! begin channel specific calculations
allocate(val(radptr%nchan))
@@ -487,10 +526,8 @@ subroutine intrad_(radhead,rval,sval,rpred,spred)
end do
end if
-!$omp parallel do schedule(dynamic,1) private(nn,ic,ix,k)
+!$omp parallel do schedule(dynamic,1) private(nn,k,ncr1,val_quad,mm)
do nn=1,radptr%nchan
- ic=radptr%icx(nn)
- ix=(ic-1)*npred
! include observation increment and lapse rate contributions to bias correction
val(nn)=zero
@@ -499,25 +536,24 @@ subroutine intrad_(radhead,rval,sval,rpred,spred)
do k=1,nsigradjac
val(nn)=val(nn)+tdir(k)*radptr%dtb_dvar(k,nn)
end do
- end do
- ncr1=0
! Include contributions from remaining bias correction terms
- do nn=1,radptr%nchan
if( .not. ladtest_obs) then
if(radptr%use_corr_obs)then
val_quad = zero_quad
do mm=1,nn
- ncr1=ncr1+1
+ ncr1=radptr%iccerr(nn)+mm
val_quad=val_quad+radptr%rsqrtinv(ncr1)*biasvect(mm)
enddo
val(nn)=val(nn) + val_quad
else
- val(nn)=val(nn)+biasvect(nn)
+ val(nn)=val(nn) + biasvect(nn)
endif
end if
+ end do
- if(luse_obsdiag)then
+ if(luse_obsdiag)then
+ do nn=1,radptr%nchan
if (lsaveobsens) then
val(nn)=val(nn)*radptr%err2(nn)*radptr%raterr2(nn)
!-- radptr%diags(nn)%ptr%obssen(jiter) = val(nn)
@@ -526,13 +562,14 @@ subroutine intrad_(radhead,rval,sval,rpred,spred)
!-- if (radptr%luse) radptr%diags(nn)%ptr%tldepart(jiter) = val(nn)
if (radptr%luse) call obsdiagNode_set(radptr%diags(nn)%ptr,jiter=jiter,tldepart=val(nn))
endif
- endif
- end do
+ end do
+ end if
if (l_do_adjoint) then
- do nn=1,radptr%nchan
- ic=radptr%icx(nn)
- if (.not. lsaveobsens) then
+ if (.not. lsaveobsens) then
+!$omp parallel do schedule(dynamic,1) private(nn,ic,cg_rad,wnotgross,wgross,p0)
+ do nn=1,radptr%nchan
+ ic=radptr%icx(nn)
if( .not. ladtest_obs) val(nn)=val(nn)-radptr%res(nn)
! Multiply by variance.
@@ -546,51 +583,45 @@ subroutine intrad_(radhead,rval,sval,rpred,spred)
endif
if(.not.ladtest_obs) val(nn) = val(nn)*radptr%err2(nn)*radptr%raterr2(nn)
- endif
- enddo
+ enddo
+ endif
! Extract contributions from bias correction terms
-! use compensated summation
if( .not. ladtest_obs) then
- if (radptr%use_corr_obs) then
- ncr1 = 0
- do mm=1,radptr%nchan
- ncr1 = ncr1 + mm
- ncr2 = ncr1
- biasvect(mm) = zero
- do nn=mm,radptr%nchan
- biasvect(mm)=biasvect(mm)+radptr%rsqrtinv(ncr2)*val(nn)
- ncr2 = ncr2 + nn
- enddo
- end do
- endif
+ if(radptr%luse)then
+ if (radptr%use_corr_obs) then
+!$omp parallel do schedule(dynamic,1) private(n,nn,ix,ncr1,ncr2,mm)
+ do nn=1,radptr%nchan
+ ncr1 = radptr%iccerr(nn)+nn
+ ncr2 = ncr1
+ biasvect(nn) = zero
+ do mm=nn,radptr%nchan
+ biasvect(nn)=biasvect(nn)+radptr%rsqrtinv(ncr2)*val(mm)
+ ncr2 = ncr2 + mm
+ enddo
- if(radptr%luse)then
- if(radptr%use_corr_obs)then
- do nn=1,radptr%nchan
- ix=(radptr%icx(nn)-1)*npred
- do n=1,npred
- rpred(ix+n)=rpred(ix+n)+biasvect(nn)*radptr%pred(n,nn)
- enddo
+ ix=(radptr%icx(nn)-1)*npred
+ do n=1,npred
+ rpred(ix+n)=rpred(ix+n)+biasvect(nn)*radptr%pred(n,nn)
enddo
- else
- do nn=1,radptr%nchan
- ix=(radptr%icx(nn)-1)*npred
- do n=1,npred
- rpred(ix+n)=rpred(ix+n)+radptr%pred(n,nn)*val(nn)
- end do
- end do
- end if
- end if
+ enddo
+ else
+!$omp parallel do schedule(dynamic,1) private(n,nn,ix)
+ do nn=1,radptr%nchan
+ ix=(radptr%icx(nn)-1)*npred
+ do n=1,npred
+ rpred(ix+n)=rpred(ix+n)+radptr%pred(n,nn)*val(nn)
+ end do
+ end do
+ end if
+ end if
- deallocate(biasvect)
+ deallocate(biasvect)
end if ! not ladtest_obs
- endif
! Begin adjoint
- if (l_do_adjoint) then
!$omp parallel do schedule(dynamic,1) private(k,nn)
do k=1,nsigradjac
tval(k)=zero
diff --git a/src/gsi/intrp2a.f90 b/src/gsi/intrp2a.f90
index 0d2926b8c7..129b48059f 100644
--- a/src/gsi/intrp2a.f90
+++ b/src/gsi/intrp2a.f90
@@ -56,8 +56,8 @@ subroutine intrp2a(f,g,dx,dy,n,nlevs,mype)
ix1=int(dx(i))
iy1=int(dy(i))
ix1=max(1,min(ix1,nlat))
- delx=dx(i)-float(ix1)
- dely=dy(i)-float(iy1)
+ delx=dx(i)-real(ix1,r_kind)
+ dely=dy(i)-real(iy1,r_kind)
delx=max(zero,min(delx,one))
ix=ix1-istart(mm1)+2
iy=iy1-jstart(mm1)+2
@@ -135,8 +135,8 @@ subroutine intrp2a1(f,g,dx,dy,nlevs,mype)
ix1=int(dx)
iy1=int(dy)
ix1=max(1,min(ix1,nlat))
- delx=dx-float(ix1)
- dely=dy-float(iy1)
+ delx=dx-real(ix1,r_kind)
+ dely=dy-real(iy1,r_kind)
delx=max(zero,min(delx,one))
ix=ix1-istart(mm1)+2
iy=iy1-jstart(mm1)+2
@@ -211,8 +211,8 @@ subroutine intrp2a11(f,g,dx,dy,mype)
ix1=int(dx)
iy1=int(dy)
ix1=max(1,min(ix1,nlat))
- delx=dx-float(ix1)
- dely=dy-float(iy1)
+ delx=dx-real(ix1,r_kind)
+ dely=dy-real(iy1,r_kind)
delx=max(zero,min(delx,one))
ix=ix1-istart(mm1)+2
iy=iy1-jstart(mm1)+2
diff --git a/src/gsi/intrw.f90 b/src/gsi/intrw.f90
index df3ec162a9..05b20e7991 100644
--- a/src/gsi/intrw.f90
+++ b/src/gsi/intrw.f90
@@ -96,7 +96,7 @@ subroutine intrw_(rwhead,rval,sval)
!$$$
use kinds, only: r_kind,i_kind
use constants, only: half,one,tiny_r_kind,cg_term,r3600
- use obsmod, only: lsaveobsens,l_do_adjoint,luse_obsdiag
+ use obsmod, only: lsaveobsens,l_do_adjoint,luse_obsdiag,if_use_w_vr
use qcmod, only: nlnqc_iter,varqc_iter
use jfunc, only: jiter
use gsi_bundlemod, only: gsi_bundle
@@ -127,23 +127,17 @@ subroutine intrw_(rwhead,rval,sval)
ier=0
call gsi_bundlegetpointer(sval,'u',su,istatus);ier=istatus+ier
call gsi_bundlegetpointer(sval,'v',sv,istatus);ier=istatus+ier
- call gsi_bundlegetpointer(sval,'w',sw,istatus)
- if (istatus==0) then
- include_w=.true.
- else
- include_w=.false.
- end if
call gsi_bundlegetpointer(rval,'u',ru,istatus);ier=istatus+ier
call gsi_bundlegetpointer(rval,'v',rv,istatus);ier=istatus+ier
- call gsi_bundlegetpointer(rval,'w',rw,istatus)
- if (istatus==0) then
- include_w=.true.
- else
- include_w=.false.
- end if
if(ier/=0)return
+ include_w=.false.
+ call gsi_bundlegetpointer(sval,'w',sw,istatus)
+ if (if_use_w_vr.and.istatus==0) then
+ call gsi_bundlegetpointer(rval,'w',rw,istatus)
+ if(istatus == 0)include_w=.true.
+ end if
!rwptr => rwhead
rwptr => rwNode_typecast(rwhead)
diff --git a/src/gsi/intsst.f90 b/src/gsi/intsst.f90
index d910247526..6b255d0d02 100644
--- a/src/gsi/intsst.f90
+++ b/src/gsi/intsst.f90
@@ -79,7 +79,7 @@ subroutine intsst(ssthead,rval,sval)
!
!$$$
use kinds, only: r_kind,i_kind
- use constants, only: half,one,tiny_r_kind,cg_term
+ use constants, only: zero,half,one,tiny_r_kind,cg_term
use obsmod, only: lsaveobsens, l_do_adjoint,luse_obsdiag
use qcmod, only: nlnqc_iter,varqc_iter
use gsi_nstcouplermod, only: nst_gsi
@@ -100,7 +100,6 @@ subroutine intsst(ssthead,rval,sval)
! real(r_kind) penalty
real(r_kind) w1,w2,w3,w4
real(r_kind) val
- real(r_kind) tval,tdir
real(r_kind) cg_sst,p0,grad,wnotgross,wgross,pg_sst
real(r_kind),pointer,dimension(:) :: ssst
real(r_kind),pointer,dimension(:) :: rsst
@@ -108,15 +107,14 @@ subroutine intsst(ssthead,rval,sval)
! If no sst data return
if(.not. associated(ssthead))return
+ if(.not. nst_gsi > 2) return
! Retrieve pointers
! Simply return if any pointer not found
- ier=0
- call gsi_bundlegetpointer(sval,'sst',ssst,istatus);ier=istatus+ier
+ call gsi_bundlegetpointer(sval,'sst',ssst,istatus);ier=istatus
call gsi_bundlegetpointer(rval,'sst',rsst,istatus);ier=istatus+ier
if(ier/=0)return
- !sstptr => ssthead
sstptr => sstNode_typecast(ssthead)
do while (associated(sstptr))
j1=sstptr%ij(1)
@@ -129,15 +127,9 @@ subroutine intsst(ssthead,rval,sval)
w4=sstptr%wij(4)
! Forward model
- val=w1*ssst(j1)+w2*ssst(j2)&
- +w3*ssst(j3)+w4*ssst(j4)
-
- if ( nst_gsi > 2 ) then
- tdir = w1*ssst(j1)+w2*ssst(j2)+w3*ssst(j3)+w4*ssst(j4) ! Forward
- val = tdir*sstptr%tz_tr ! Include contributions from Tz jacobian
- else
- val = w1*ssst(j1)+w2*ssst(j2)+w3*ssst(j3)+w4*ssst(j4) ! Forward
- endif
+ val=w1*ssst(j1)+w2*ssst(j2)+w3*ssst(j3)+w4*ssst(j4)
+
+ val = val*sstptr%tz_tr ! Include contributions from Tz jacobian
if(luse_obsdiag)then
@@ -173,18 +165,12 @@ subroutine intsst(ssthead,rval,sval)
endif
! Adjoint
- if ( nst_gsi > 2 ) then
- tval = sstptr%tz_tr*grad ! Extract contributions from surface jacobian
- rsst(j1)=rsst(j1)+w1*tval ! Distribute adjoint contributions over surrounding grid points
- rsst(j2)=rsst(j2)+w2*tval
- rsst(j3)=rsst(j3)+w3*tval
- rsst(j4)=rsst(j4)+w4*tval
- else
- rsst(j1)=rsst(j1)+w1*grad
- rsst(j2)=rsst(j2)+w2*grad
- rsst(j3)=rsst(j3)+w3*grad
- rsst(j4)=rsst(j4)+w4*grad
- endif
+ grad = sstptr%tz_tr*grad ! Extract contributions from surface jacobian
+
+ rsst(j1)=rsst(j1)+w1*grad
+ rsst(j2)=rsst(j2)+w2*grad
+ rsst(j3)=rsst(j3)+w3*grad
+ rsst(j4)=rsst(j4)+w4*grad
endif ! if (l_do_adjoint) then
diff --git a/src/gsi/intt.f90 b/src/gsi/intt.f90
index 9401026e47..b4082712a9 100644
--- a/src/gsi/intt.f90
+++ b/src/gsi/intt.f90
@@ -145,7 +145,7 @@ subroutine intt_(thead,rval,sval,rpred,spred)
! Declare local variables
integer(i_kind) j1,j2,j3,j4,j5,j6,j7,j8,ier,istatus,isst,ix,n
- real(r_kind) w1,w2,w3,w4,w5,w6,w7,w8,time_t
+ real(r_kind) w1,w2,w3,w4,w5,w6,w7,w8
! real(r_kind) penalty
real(r_kind) cg_t,val,grad,rat_err2,error2,t_pg,var_jb
real(r_kind) psfc_grad,tg_grad
@@ -160,14 +160,13 @@ subroutine intt_(thead,rval,sval,rpred,spred)
! Retrieve pointers
! Simply return if any pointer not found
- ier=0; isst=0
- call gsi_bundlegetpointer(sval,'tsen', st,istatus);ier=istatus+ier
+ call gsi_bundlegetpointer(sval,'tsen', st,istatus);ier=istatus
call gsi_bundlegetpointer(sval,'tv', stv,istatus);ier=istatus+ier
call gsi_bundlegetpointer(sval,'q', sq,istatus);ier=istatus+ier
call gsi_bundlegetpointer(sval,'u', su,istatus);ier=istatus+ier
call gsi_bundlegetpointer(sval,'v', sv,istatus);ier=istatus+ier
call gsi_bundlegetpointer(sval,'prse', sp,istatus);ier=istatus+ier
- call gsi_bundlegetpointer(sval,'sst',ssst,istatus);isst=istatus+isst
+ call gsi_bundlegetpointer(sval,'sst',ssst,istatus);isst=istatus
if(ier/=0) return
call gsi_bundlegetpointer(rval,'tsen', rt,istatus);ier=istatus+ier
@@ -179,7 +178,6 @@ subroutine intt_(thead,rval,sval,rpred,spred)
call gsi_bundlegetpointer(rval,'sst',rsst,istatus);isst=istatus+isst
if(ier/=0) return
- time_t=zero
!tptr => thead
tptr => tNode_typecast(thead)
do while (associated(tptr))
@@ -205,20 +203,22 @@ subroutine intt_(thead,rval,sval,rpred,spred)
!----------use surface model----------------------
+ qs_prime0=w1* sq(j1)+w2* sq(j2)+w3* sq(j3)+w4* sq(j4)
+ us_prime0=w1* su(j1)+w2* su(j2)+w3* su(j3)+w4* su(j4)
+ vs_prime0=w1* sv(j1)+w2* sv(j2)+w3* sv(j3)+w4* sv(j4)
+ psfc_prime0=w1* sp(j1)+w2* sp(j2)+w3* sp(j3)+w4* sp(j4)
+
if(tptr%tv_ob)then
ts_prime0=w1*stv(j1)+w2*stv(j2)+w3*stv(j3)+w4*stv(j4)
else
ts_prime0=w1*st(j1)+w2*st(j2)+w3*st(j3)+w4*st(j4)
end if
+
if (isst==0) then
tg_prime0=w1* ssst(j1)+w2*ssst(j2)+w3*ssst(j3)+w4*ssst(j4)
else
tg_prime0=zero
end if
- qs_prime0=w1* sq(j1)+w2* sq(j2)+w3* sq(j3)+w4* sq(j4)
- us_prime0=w1* su(j1)+w2* su(j2)+w3* su(j3)+w4* su(j4)
- vs_prime0=w1* sv(j1)+w2* sv(j2)+w3* sv(j3)+w4* sv(j4)
- psfc_prime0=w1* sp(j1)+w2* sp(j2)+w3* sp(j3)+w4* sp(j4)
val=psfc_prime0*tptr%tlm_tsfc(1) + tg_prime0*tptr%tlm_tsfc(2) + &
ts_prime0 *tptr%tlm_tsfc(3) + qs_prime0*tptr%tlm_tsfc(4) + &
@@ -231,8 +231,8 @@ subroutine intt_(thead,rval,sval,rpred,spred)
val=w1*stv(j1)+w2*stv(j2)+w3*stv(j3)+w4*stv(j4)&
+w5*stv(j5)+w6*stv(j6)+w7*stv(j7)+w8*stv(j8)
else
- val=w1* st(j1)+w2* st(j2)+w3* st(j3)+w4* st(j4)&
- +w5* st(j5)+w6* st(j6)+w7* st(j7)+w8* st(j8)
+ val=w1*st(j1)+ w2*st(j2)+ w3*st(j3)+ w4*st(j4)&
+ +w5*st(j5)+ w6*st(j6)+ w7*st(j7)+ w8*st(j8)
end if
end if
@@ -310,21 +310,7 @@ subroutine intt_(thead,rval,sval,rpred,spred)
rp(j2)=rp(j2)+w2*psfc_grad
rp(j3)=rp(j3)+w3*psfc_grad
rp(j4)=rp(j4)+w4*psfc_grad
- vs_grad =tptr%tlm_tsfc(6)*grad
- rv(j1)=rv(j1)+w1*vs_grad
- rv(j2)=rv(j2)+w2*vs_grad
- rv(j3)=rv(j3)+w3*vs_grad
- rv(j4)=rv(j4)+w4*vs_grad
- us_grad =tptr%tlm_tsfc(5)*grad
- ru(j1)=ru(j1)+w1*us_grad
- ru(j2)=ru(j2)+w2*us_grad
- ru(j3)=ru(j3)+w3*us_grad
- ru(j4)=ru(j4)+w4*us_grad
- qs_grad =tptr%tlm_tsfc(4)*grad
- rq(j1)=rq(j1)+w1*qs_grad
- rq(j2)=rq(j2)+w2*qs_grad
- rq(j3)=rq(j3)+w3*qs_grad
- rq(j4)=rq(j4)+w4*qs_grad
+
if (isst==0) then
tg_grad =tptr%tlm_tsfc(2)*grad
rsst(j1)=rsst(j1)+w1*tg_grad
@@ -333,22 +319,39 @@ subroutine intt_(thead,rval,sval,rpred,spred)
rsst(j4)=rsst(j4)+w4*tg_grad
end if
-
ts_grad =tptr%tlm_tsfc(3)*grad
if(tptr%tv_ob)then
rtv(j1)=rtv(j1)+w1*ts_grad
rtv(j2)=rtv(j2)+w2*ts_grad
rtv(j3)=rtv(j3)+w3*ts_grad
rtv(j4)=rtv(j4)+w4*ts_grad
-
else
rt(j1)=rt(j1)+w1*ts_grad
rt(j2)=rt(j2)+w2*ts_grad
rt(j3)=rt(j3)+w3*ts_grad
rt(j4)=rt(j4)+w4*ts_grad
-
end if
+ qs_grad =tptr%tlm_tsfc(4)*grad
+ rq(j1)=rq(j1)+w1*qs_grad
+ rq(j2)=rq(j2)+w2*qs_grad
+ rq(j3)=rq(j3)+w3*qs_grad
+ rq(j4)=rq(j4)+w4*qs_grad
+
+ us_grad =tptr%tlm_tsfc(5)*grad
+ ru(j1)=ru(j1)+w1*us_grad
+ ru(j2)=ru(j2)+w2*us_grad
+ ru(j3)=ru(j3)+w3*us_grad
+ ru(j4)=ru(j4)+w4*us_grad
+
+ vs_grad =tptr%tlm_tsfc(6)*grad
+ rv(j1)=rv(j1)+w1*vs_grad
+ rv(j2)=rv(j2)+w2*vs_grad
+ rv(j3)=rv(j3)+w3*vs_grad
+ rv(j4)=rv(j4)+w4*vs_grad
+
+
+
else
!------bypass surface model--------------------------
diff --git a/src/gsi/jfunc.f90 b/src/gsi/jfunc.f90
index 1b92ad2e94..616f835218 100644
--- a/src/gsi/jfunc.f90
+++ b/src/gsi/jfunc.f90
@@ -136,10 +136,12 @@ module jfunc
public :: pseudo_q2
public :: varq
public :: cnvw_option
+ public :: hofx_2m_sfcfile
logical first,last,switch_on_derivatives,tendsflag,print_diag_pcg,tsensible,diag_precon
logical clip_supersaturation,R_option
logical pseudo_q2,limitqobs
+ logical hofx_2m_sfcfile
logical cnvw_option
integer(i_kind) iout_iter,miter,iguess,nclen,qoption,cwoption
integer(i_kind) jiter,jiterstart,jiterend,iter
@@ -249,6 +251,9 @@ subroutine init_jfunc
! option for including convective clouds in the all-sky assimilation
cnvw_option=.false.
+! option to calculate hofx for T2m and q2m by interpolating from 2m vars in sfc file
+ hofx_2m_sfcfile=.false.
+
return
end subroutine init_jfunc
diff --git a/src/gsi/jgrad.f90 b/src/gsi/jgrad.f90
index 2e32556465..6b17544300 100755
--- a/src/gsi/jgrad.f90
+++ b/src/gsi/jgrad.f90
@@ -58,6 +58,8 @@ subroutine jgrad(xhat,yhat,fjcost,gradx,lupdfgs,nprt,calledby)
use hybrid_ensemble_parameters,only : l_hyb_ens,ntlevs_ens
use mpl_allreducemod, only: mpl_allreduce
use obs_sensitivity, only: efsoi_o2_update
+use control2state_mod, only: control2state,control2state_ad
+use ensctl2state_mod, only: ensctl2state,ensctl2state_ad
implicit none
diff --git a/src/gsi/lightinfo.f90 b/src/gsi/lightinfo.f90
index b0ebcdacfd..bdd6aee392 100755
--- a/src/gsi/lightinfo.f90
+++ b/src/gsi/lightinfo.f90
@@ -205,11 +205,13 @@ subroutine lightinfo_read
else
! File does not exist, write warning message to alert users
- if (mype==mype_light) then
- open(iout_light)
- write(iout_light,*)'LIGHTINFO_READ: ***WARNING*** FILE ',trim(fname),'does not exist'
- close(iout_light)
- endif
+! For many usages light data is not important. Write line to output.
+! if (mype==mype_light) then
+! open(iout_light)
+! write(iout_light,*)'LIGHTINFO_READ: ***WARNING*** FILE ',trim(fname),'does not exist'
+ if(mype==mype_light)write(6,*)'LIGHTINFO_READ: FILE ',trim(fname),'does not exist'
+! close(iout_light)
+! endif
end if
return
diff --git a/src/gsi/m_berror_stats.f90 b/src/gsi/m_berror_stats.f90
index 808aee9954..088a7619fe 100644
--- a/src/gsi/m_berror_stats.f90
+++ b/src/gsi/m_berror_stats.f90
@@ -646,7 +646,7 @@ subroutine setcoroz_(coroz,mype)
enddo
enddo
enddo
- work_oz(nsig+1,mm1)=float(lon1*lat1)
+ work_oz(nsig+1,mm1)=real(lon1*lat1,r_kind)
call mpi_allreduce(work_oz,work_oz1,(nsig+1)*npe,mpi_rtype,mpi_sum,&
mpi_comm_world,ierror)
@@ -869,7 +869,7 @@ subroutine setcorchem_(cname,corchem,rc)
enddo
enddo
enddo
- work_chem(nsig+1,mm1)=float(lon1*lat1)
+ work_chem(nsig+1,mm1)=real(lon1*lat1,r_kind)
call mpi_allreduce(work_chem,work_chem1,(nsig+1)*npe,mpi_rtype,mpi_sum,&
mpi_comm_world,ierror)
diff --git a/src/gsi/m_berror_stats_reg.f90 b/src/gsi/m_berror_stats_reg.f90
index 2ff8a6aa94..d7a30808e6 100644
--- a/src/gsi/m_berror_stats_reg.f90
+++ b/src/gsi/m_berror_stats_reg.f90
@@ -12,7 +12,7 @@ module m_berror_stats_reg
use kinds,only : i_kind,r_kind
use constants, only: zero,one,max_varname_length,half
use gridmod, only: nsig
- use chemmod, only : berror_chem,berror_fv3_cmaq_regional,upper2lower,lower2upper
+ use chemmod, only : berror_chem,berror_fv3_cmaq_regional,berror_fv3_sd_regional,upper2lower,lower2upper
use m_berror_stats, only: usenewgfsberror,berror_stats
implicit none
@@ -312,7 +312,8 @@ subroutine berror_read_wgt_reg(msig,mlat,corz,corp,hwll,hwllp,vz,rlsig,varq,qopt
use constants, only: zero,one,ten,three
use mpeu_util,only: getindex
use radiance_mod, only: icloud_cv,n_clouds_fwd,cloud_names_fwd
- use chemmod, only: berror_fv3_cmaq_regional
+ use chemmod, only: berror_fv3_cmaq_regional,berror_fv3_sd_regional
+ use rapidrefresh_cldsurf_mod, only: corp_gust, hwllp_gust, l_rtma3d
implicit none
@@ -400,7 +401,7 @@ subroutine berror_read_wgt_reg(msig,mlat,corz,corp,hwll,hwllp,vz,rlsig,varq,qopt
integer(i_kind) :: nrf2_td2m,nrf2_mxtm,nrf2_mitm,nrf2_pmsl,nrf2_howv,nrf2_tcamt,nrf2_lcbas,nrf2_cldch
integer(i_kind) :: nrf2_uwnd10m,nrf2_vwnd10m
integer(i_kind) :: nrf3_sfwter,nrf3_vpwter
- integer(i_kind) :: nrf3_dbz
+ integer(i_kind) :: nrf3_dbz,nrf3_fed
integer(i_kind) :: nrf3_ql,nrf3_qi,nrf3_qr,nrf3_qs,nrf3_qg,nrf3_qnr,nrf3_w
integer(i_kind) :: inerr,istat
integer(i_kind) :: nsigstat,nlatstat,isig
@@ -466,7 +467,7 @@ subroutine berror_read_wgt_reg(msig,mlat,corz,corp,hwll,hwllp,vz,rlsig,varq,qopt
var=upper2lower(varshort)
if (trim(var) == 'pm25') var = 'pm2_5'
else
- if ( berror_fv3_cmaq_regional) then
+ if ( berror_fv3_cmaq_regional .or. berror_fv3_sd_regional) then
read(inerr,iostat=istat) varlong, isig
var=varlong
else
@@ -624,6 +625,7 @@ subroutine berror_read_wgt_reg(msig,mlat,corz,corp,hwll,hwllp,vz,rlsig,varq,qopt
nrf3_sf =getindex(cvars3d,'sf')
nrf3_vp =getindex(cvars3d,'vp')
nrf3_dbz=getindex(cvars3d,'dbz')
+ nrf3_fed=getindex(cvars3d,'fed')
nrf2_sst=getindex(cvars2d,'sst')
nrf2_gust=getindex(cvars2d,'gust')
nrf2_vis=getindex(cvars2d,'vis')
@@ -671,6 +673,16 @@ subroutine berror_read_wgt_reg(msig,mlat,corz,corp,hwll,hwllp,vz,rlsig,varq,qopt
vz(:,:,nrf3_dbz)=vz(:,:,nrf3_t)
endif
+ if( nrf3_fed>0 )then
+ if(.not. nrf3_t>0) then
+ write(6,*)'not as expect,stop'
+ stop
+ endif
+ corz(:,:,nrf3_fed)=10.0_r_kind
+ hwll(:,:,nrf3_fed)=hwll(:,:,nrf3_t)
+ vz(:,:,nrf3_fed)=vz(:,:,nrf3_t)
+ endif
+
if (nrf3_oz>0) then
factoz = 0.0002_r_kind*r25
corz(:,:,nrf3_oz)=factoz
@@ -814,11 +826,35 @@ subroutine berror_read_wgt_reg(msig,mlat,corz,corp,hwll,hwllp,vz,rlsig,varq,qopt
! end if
else if (n==nrf2_gust) then
do i=1,mlat
- corp(i,n)=three
+ corp(i,n)=three ! background error stddev of wind gust = 3 m/s (default: legacy code from 2DRTMA)
end do
do i=0,mlat+1
- hwllp(i,n)=hwll(i,1,nrf3_q)
+ hwllp(i,n)=hwll(i,1,nrf3_q) ! de-correlation length of bkgd error of gust is
+ ! same as the value of q at bottom level (default: legacy code from 2DRTMA)
+ ! for other DA apps, it is recommended to change it
+ ! by setting hwllp_gust in GSI namelist.
end do
+ if ( l_rtma3d ) then ! For 3drtma only: allowing to change the stddev and
+ ! de-correlation length of bkgd error of gust:
+ ! corp_gust : set in namelist(if <=0, using default value above (3.0)
+ ! hwllp_gust: set in namelist(if <=0, using default value above (value of q)
+ if ( corp_gust .gt. 0.0_r_kind ) then
+ corp(1:mlat, n) = corp_gust
+ if (mype==0) write(6,'(1x,A,A,I5.5,A,F8.3)') &
+ myname_,"@pe=",mype," (3drtma) set b_error stddev of gust = ",corp_gust
+ else
+ if (mype==0) write(6,'(1x,A,A,I5.5,A,F8.3)') &
+ myname_,"@pe=",mype," (3drtma) set b_error stddev of gust (default) = ",three
+ end if
+ if ( hwllp_gust .gt. 0.0_r_kind ) then
+ hwllp(0:mlat+1,n) = hwllp_gust
+ if (mype==0) write(6,'(1x,A,A,I5.5,A,F12.3)') &
+ myname_,"@pe=",mype," (3drtma) set b_error de-corr length of gust = ",hwllp_gust
+ else
+ if (mype==0) write(6,'(1x,A,A,I5.5,A)') &
+ myname_,"@pe=",mype," (3drtma) set b_error de-corr length of gust is same as length of q."
+ end if
+ end if
else if (n==nrf2_vis) then
do i=1,mlat
corp(i,n)=3.0_r_kind
@@ -870,16 +906,17 @@ subroutine berror_read_wgt_reg(msig,mlat,corz,corp,hwll,hwllp,vz,rlsig,varq,qopt
hwllp(i,n)=hwllp(i,nrf2_ps)
end do
else if (n==nrf2_howv) then
- call read_howv_stats(mlat,1,2,cov_dum)
+ call read_howv_stats(mlat,1,2,cov_dum,mype)
do i=1,mlat
corp(i,n)=cov_dum(i,1,1) !#ww3
hwllp(i,n) = cov_dum(i,1,2)
end do
hwllp(0,n) = hwllp(1,n)
hwllp(mlat+1,n) = hwllp(mlat,n)
-
- if (mype==0) print*, 'corp(i,n) = ', corp(:,n)
- if (mype==0) print*, ' hwllp(i,n) = ', hwllp(:,n)
+ if (mype==0) then
+ print*, myname_, ' static BE corp( :,n) (for ', trim(adjustl(cvars2d(n))), ')= ', corp(:,n)
+ print*, myname_, ' static BE hwllp(:,n) (for ', trim(adjustl(cvars2d(n))), ')= ', hwllp(:,n)
+ end if
! corp(:,n)=cov_dum(:,1)
!do i=1,mlat
! corp(i,n)=0.4_r_kind !#ww3
@@ -1055,7 +1092,7 @@ subroutine berror_read_wgt_reg(msig,mlat,corz,corp,hwll,hwllp,vz,rlsig,varq,qopt
end subroutine berror_read_wgt_reg
!++++
-subroutine read_howv_stats(nlat,nlon,npar,arrout)
+subroutine read_howv_stats(nlat,nlon,npar,arrout,mype)
!$$$ subprogram documentation block
! . . . .
! subprogram: read_howv_stats
@@ -1090,6 +1127,9 @@ subroutine read_howv_stats(nlat,nlon,npar,arrout)
! program history log:
! 2016-08-03 stelios
! 2016-08-26 stelios : Compatible with GSI.
+! 2023-07-30 Zhao - added code to set the background error
+! standard deviation (corp_howv) and de-correlation
+! length scale (hwllp_howv) for non-2DRTMA run
! input argument list:
! filename - The name of the file
! output argument list:
@@ -1102,10 +1142,14 @@ subroutine read_howv_stats(nlat,nlon,npar,arrout)
!$$$ end documentation block
!
use kinds,only : r_kind, i_kind
+ use gridmod, only : twodvar_regional
+ use rapidrefresh_cldsurf_mod, only : corp_howv, hwllp_howv
+ use gsi_io, only : verbose
!
implicit none
! Declare passed variables
integer(i_kind), intent(in )::nlat,nlon,npar
+ integer(i_kind), intent(in ) :: mype ! "my" processor ID
real(r_kind), dimension(nlat ,nlon, npar), intent( out)::arrout
! Declare local variables
integer(i_kind) :: reclength,i,j,i_npar
@@ -1117,12 +1161,18 @@ subroutine read_howv_stats(nlat,nlon,npar,arrout)
!
filename(1) = 'howv_var_berr.bin'
filename(2) = 'howv_lng_berr.bin'
-!
- arrout(:,:,1)=0.42_r_kind
- arrout(:,:,2)=50000.0_r_kind
+!-- first, assign the pre-defined values to corp and hwllp
+ if ( twodvar_regional ) then
+ arrout(:,:,1)=0.42_r_kind ! values were specified by Manuel and Stelio for 2DRTMA
+ arrout(:,:,2)=50000.0_r_kind ! values were specified by Manuel and Stelio for 2DRTMA
+ else
+ arrout(:,:,1) = corp_howv ! 0.42_r_kind used in 3dvar (default) if not set in namelist
+ arrout(:,:,2) = hwllp_howv ! 17000.0_r_kind used in 3dvar (default) if not set in namelist
+ end if
reclength=nlat*r_kind
-!
+!-- secondly, if files for corp and hwllp are available, then read them in for
+! corp and hwllp. If the files are not found, then use the pre-defined values.
do i_npar = 1,npar
inquire(file=trim(filename(i_npar)), exist=file_exists)
if (file_exists)then
@@ -1132,9 +1182,16 @@ subroutine read_howv_stats(nlat,nlon,npar,arrout)
read(unit=lun34 ,rec=j) (arrout(i,j,i_npar), i=1,nlat)
enddo
close(unit=lun34)
+ if (verbose .and. mype .eq. 0) then
+ write(6,'(1x,A,1x,A2,1x,A)') trim(adjustl(myname)), '::', &
+ trim(filename(i_npar))//' is used for background error of howv.'
+ end if
else
- print*,myname, trim(filename(i_npar)) // ' does not exist'
+ if (verbose .and. mype .eq. 0) then
+ write(6,'(1x,A,1x,A2,1x,A)') trim(adjustl(myname)), '::', &
+ trim(filename(i_npar))//' does not exist for static BE of howv, using pre-defined values.'
+ end if
end if
end do
end subroutine read_howv_stats
diff --git a/src/gsi/m_extOzone.F90 b/src/gsi/m_extOzone.F90
index 3d4b6783c1..5dead0551a 100644
--- a/src/gsi/m_extOzone.F90
+++ b/src/gsi/m_extOzone.F90
@@ -158,32 +158,36 @@ function is_extOzone_(dfile,dtype,dplat,class)
is_extOzone_= &
ifile_==iBUFR .and. dtype == 'o3lev' .or. &
ifile_==iNC .and. dtype == 'mls55' .or. &
+ ifile_==iNC .and. dtype == 'ompslpnc' .or. &
ifile_==iNC .and. dtype == 'ompslpvis' .or. &
ifile_==iNC .and. dtype == 'ompslpuv' .or. &
- ifile_==iNC .and. dtype == 'ompslp' .or. &
ifile_==iNC .and. dtype == 'lims' .or. &
ifile_==iNC .and. dtype == 'uarsmls' .or. &
ifile_==iNC .and. dtype == 'mipas' .or. &
ifile_==iNC .and. dtype == 'omieff' .or. &
+ ifile_==iNC .and. dtype == 'ompsnmeff' .or. &
+ ifile_==iNC .and. dtype == 'ompsnpnc' .or. &
ifile_==iNC .and. dtype == 'tomseff'
case(iLEVEL)
is_extOzone_= &
ifile_==iBUFR .and. dtype == 'o3lev' .or. &
ifile_==iNC .and. dtype == 'mls55' .or. &
+ ifile_==iNC .and. dtype == 'ompslpnc' .or. &
ifile_==iNC .and. dtype == 'ompslpvis' .or. &
ifile_==iNC .and. dtype == 'ompslpuv' .or. &
- ifile_==iNC .and. dtype == 'ompslp' .or. &
ifile_==iNC .and. dtype == 'lims' .or. &
ifile_==iNC .and. dtype == 'uarsmls' .or. &
ifile_==iNC .and. dtype == 'mipas'
case(iLAYER)
- is_extOzone_= .false.
+ is_extOzone_= &
+ ifile_==iNC .and. dtype == 'ompsnpnc'
case(iTOTAL)
is_extOzone_= &
- ifile_==iNC .and. dtype == 'omieff' .or. &
+ ifile_==iNC .and. dtype == 'omieff' .or. &
+ ifile_==iNC .and. dtype == 'ompsnmeff' .or. &
ifile_==iNC .and. dtype == 'tomseff'
case default
@@ -332,7 +336,7 @@ subroutine read_(dfile,dtype,dplat,dsis, & ! intent(in), keys for type mana
endif
select case(dtype)
- case('omieff','tomseff') ! layer-ozone or total-ozone types
+ case('omieff','tomseff','ompsnmeff') ! layer-ozone or total-ozone types
select case(dfile_format(dfile))
case('nc')
call oztot_ncInquire_(nreal,nchan,ilat,ilon, &
@@ -381,7 +385,7 @@ subroutine read_(dfile,dtype,dplat,dsis, & ! intent(in), keys for type mana
jsatid, gstime,twind)
end select
- case('mls55','ompslpvis','ompslpuv','ompslp','lims','uarsmls','mipas')
+ case('mls55','ompslpnc','ompslpvis','ompslpuv','lims','uarsmls','mipas')
select case(dfile_format(dfile))
case('nc')
call ozlev_ncInquire_( nreal,nchan,ilat,ilon,maxobs)
@@ -393,6 +397,17 @@ subroutine read_(dfile,dtype,dplat,dsis, & ! intent(in), keys for type mana
end select
+ case('ompsnpnc')
+ select case(dfile_format(dfile))
+ case('nc')
+ call ozlay_ncInquire_( nreal,nchan,ilat,ilon,maxobs)
+ allocate(p_out(nreal+nchan,maxobs))
+ p_out(:,:)=RMISS
+
+ call ozlay_ncRead_(dfile,dtype, p_out,nread,npuse,nouse, gstime,twind)
+
+ end select
+
end select
if(nouse<0 .or. .not.associated(p_out)) then
@@ -706,7 +721,7 @@ subroutine oztot_ncread_(dfile,dtype,dsis, ozout,nmrecs,ndata,nodata, &
! Apply data screening based on quality flags
! Bit 10 (from the left) in TOQF represents row anomaly. All 17 bits in toqf is
! supposed to converted into array elements of binary(:), either for "tomseff" or
-! "omieff".
+! "omieff" or "ompsnmeff".
binary(:)=0
select case(dtype)
case('omieff')
@@ -731,6 +746,9 @@ subroutine oztot_ncread_(dfile,dtype,dsis, ozout,nmrecs,ndata,nodata, &
! 0 - good data, 1 - good data with SZA > 84 deg
if (toqf /= 0) cycle recloop
+ case('ompsnmeff')
+ !! data in NetCDF are prescreened
+
case default
end select
@@ -764,10 +782,10 @@ subroutine oztot_ncread_(dfile,dtype,dsis, ozout,nmrecs,ndata,nodata, &
ozout(7,itx)=real(toqf) ! - total ozone quality code (not used)
ozout(8,itx)=real(sza) ! solar zenith angle
ozout(9,itx)=binary(10) ! row anomaly flag, is actually fixed to 0
- ozout(10,itx)=0. ! - cloud amount (not used)
- ozout(11,itx)=0. ! - vzan (not used)
- ozout(12,itx)=0. ! - aerosol index (not used)
- ozout(13,itx)=0. ! - ascending/descending (not used)
+ ozout(10,itx)=zero ! - cloud amount (not used)
+ ozout(11,itx)=zero ! - vzan (not used)
+ ozout(12,itx)=zero ! - aerosol index (not used)
+ ozout(13,itx)=zero ! - ascending/descending (not used)
ozout(14,itx)=real(fovn) ! scan position
! "(not used)" flags above imply that they
! are not used in setupozlay().
@@ -1093,7 +1111,7 @@ subroutine ozlev_ncread_(dfile,dtype,ozout,nmrecs,ndata,nodata, gstime,twind)
ozout(8,ndata)=usage
ozout(9,ndata)=pob ! pressure
ozout(10,ndata)=obserr ! ozone mixing ratio precision in ppmv
- ozout(11,ndata)=float(ipos(ilev)) ! pointer of obs level index in ozinfo.txt
+ ozout(11,ndata)=real(ipos(ilev),r_kind) ! pointer of obs level index in ozinfo.txt
ozout(12,ndata)=levs ! # of vertical levels
ozout(13,ndata)=ppmv ! ozone mixing ratio in ppmv
endif
@@ -1406,7 +1424,7 @@ subroutine ozlev_bufrread_(dfile,dtype,dsis, ozout,nmrecs,ndata,nodata, &
ozout( 8,ndata)=usage1(k) !
ozout( 9,ndata)=mlspres(k) ! mls pressure in log(cb)
ozout(10,ndata)=mlsozpc(k) ! ozone mixing ratio precision in ppmv
- ozout(11,ndata)=float(ipos(k)) ! pointer of obs level index in ozinfo.txt
+ ozout(11,ndata)=real(ipos(k),r_kind) ! pointer of obs level index in ozinfo.txt
ozout(12,ndata)=nloz ! # of mls vertical levels
ozout(13,ndata)=mlsoz(k) ! ozone mixing ratio in ppmv
endif
@@ -1421,13 +1439,286 @@ subroutine ozlev_bufrread_(dfile,dtype,dsis, ozout,nmrecs,ndata,nodata, &
call warn(myname_,' actual retained =',nodata)
call warn(myname_,' size(ozout,2) =',maxobs)
endif
- call closbf(lunin)
- close(lunin)
! write(stdout,'(3a,3i8,f8.2)') mprefix('read_ozone'), &
! ' obstype,nmrecs,ndata,nodata,no/ndata = ',dtype,nmrecs,ndata,nodata,real(nodata)/ndata
-end subroutine ozlev_bufrread_
+ end subroutine ozlev_bufrread_
+
+ subroutine ozlay_ncInquire_( nreal,nchan,ilat,ilon, maxrec)
+ implicit none
+
+ integer(kind=i_kind), intent(out):: nreal ! number of real parameters per record
+ integer(kind=i_kind), intent(out):: nchan ! number of channels or levels per record
+ integer(kind=i_kind), intent(out):: ilat ! index to latitude in nreal parameters.
+ integer(kind=i_kind), intent(out):: ilon ! index to longitude in nreal parameters.
+
+ integer(kind=i_kind), intent(out):: maxrec ! extimated input record count
+
+ character(len=*), parameter:: myname_=myname//'::ozlay_ncInquire_'
+
+ ! Configure the record, they are not (dfile,dtype,dplat) dependent in this case.
+ nreal = 9
+ nchan = 22
+ ilat=4
+ ilon=3
+
+ maxrec = MAXOBS_
+ end subroutine ozlay_ncInquire_
+
+ !..................................................................................
+ subroutine ozlay_ncread_(dfile,dtype,ozout,nmrecs,ndata,nodata, gstime,twind)
+ !..................................................................................
+ use netcdf, only: nf90_open
+ use netcdf, only: nf90_nowrite
+ use netcdf, only: nf90_noerr
+ use netcdf, only: nf90_inq_dimid
+ use netcdf, only: nf90_inquire_dimension
+ use netcdf, only: nf90_inq_varid
+ use netcdf, only: nf90_get_var
+ use netcdf, only: nf90_close
+
+ use gridmod, only: nlat,nlon,regional,tll2xy,rlats,rlons
+ use gsi_4dvar, only: l4dvar,iwinbgn,winlen,l4densvar
+
+ use constants, only: deg2rad,zero,one_tenth,r60inv
+ use ozinfo, only: jpch_oz,nusis_oz,iuse_oz
+ use mpeu_util, only: perr,die
+ ! use mpeu_util, only: mprefix,stdout
+
+ implicit none
+ character(len=*), intent(in):: dfile ! obs_input filename
+ character(len=*), intent(in):: dtype ! obs_input dtype
+ real (kind=r_kind), dimension(:,:), intent(out):: ozout
+ integer(kind=i_kind), intent(out):: nmrecs ! count of records read
+ integer(kind=i_kind), intent(out):: ndata ! count of processed
+ integer(kind=i_kind), intent(out):: nodata ! count of retained
+ real (kind=r_kind), intent(in):: gstime ! analysis time (minute) from reference date
+ real (kind=r_kind), intent(in):: twind ! input group time window (hour)
+
+ character(len=*), parameter:: myname_=myname//'::ozlay_ncRead_'
+
+ integer(kind=i_kind):: ier,nprofs,levs,ikx,i,k0,ilev,iprof
+ integer(kind=i_kind):: nrecDimId,lonVarID,latVarID,yyVarID,mmVarID,levsDimId
+ integer(kind=i_kind):: szaVarID,ozoneVarID,nmind,k
+ integer(kind=i_kind):: ddVarID,hhVarID,minVarID,ssVarID,maxobs,ncid
+ real (kind=r_kind):: dlon,dlon_earth,dlon_earth_deg
+ real (kind=r_kind):: dlat,dlat_earth,dlat_earth_deg
+ real (kind=r_kind):: slons0,slats0
+ real (kind=r_kind):: tdiff,sstime,t4dv,rsat
+ integer(kind=i_kind):: idate5(5)
+ integer(kind=i_kind),allocatable,dimension(:):: ipos
+ real(r_kind),allocatable,dimension(:):: poz
+
+ integer(kind=i_kind), allocatable :: iya(:),ima(:),idda(:),ihha(:),imina(:),iseca(:)
+ real (kind=r_kind), allocatable :: slatsa(:),slonsa(:),ozone(:,:),sza(:)
+ real(r_kind) totoz
+
+ logical:: outside
+ logical:: first
+ real(r_kind),parameter:: badoz = 10000.0_r_kind
+
+ maxobs=size(ozout,2)
+ rsat=999._r_kind
+ ndata = 0
+ nmrecs=0
+ nodata=-1
+
+ ! Open file and read dimensions
+ call check(nf90_open(trim(dfile),nf90_nowrite,ncid),stat=ier)
+
+ ! ignore if the file is not actually present.
+ if(ier/=nf90_noerr) then
+ nodata = 0
+ return
+ endif
+
+ ! Get dimensions from the input file
+ call check(nf90_inq_dimid(ncid, "nrec", nrecDimId),stat=ier)
+
+ ! ignore if error
+ if(ier/=nf90_noerr) then
+ nodata = 0
+ call check(nf90_close(ncid),stat=ier)
+ return
+ endif
+
+ ! Get dimensions from the input file: # of profiles and # of levels
+ nprofs=0
+ call check(nf90_inquire_dimension(ncid, nrecDimId, len = nprofs),stat=ier)
+ ! ignore if error
+ if(ier/=nf90_noerr) then
+ call check(nf90_close(ncid),stat=ier)
+ return
+ endif
+
+ if(nprofs==0) then
+ nodata=0
+ call check(nf90_close(ncid),stat=ier)
+ return
+ endif
+
+ ! Continue the input
+ call check(nf90_inq_dimid(ncid, "nlevs", levsDimId))
+ call check(nf90_inquire_dimension(ncid, levsDimId, len = levs))
+ !!!!! if (levs /= nchan)
+
+ allocate(ipos(levs))
+ ipos=999
+ ikx = 0
+ first=.false.
+ do i=1,jpch_oz
+ if( (.not. first) .and. index(nusis_oz(i), trim(dtype))/=0) then
+ k0=i
+ first=.true.
+ end if
+ if(first.and.index(nusis_oz(i),trim(dtype))/=0) then
+ ikx=ikx+1
+ ipos(ikx)=k0+ikx-1
+ end if
+ end do
+
+ if (ikx/=levs+1) call die(myname_//': inconsistent levs for '//dtype)
+
+ ! Allocate space and read data
+ allocate(iya(nprofs),ima(nprofs),idda(nprofs),ihha(nprofs),imina(nprofs), &
+ iseca(nprofs),slatsa(nprofs),slonsa(nprofs),sza(nprofs),ozone(levs,nprofs))
+ allocate (poz(levs+1))
+
+ call check(nf90_inq_varid(ncid, "lon", lonVarId))
+ call check(nf90_get_var(ncid, lonVarId, slonsa))
+
+ call check(nf90_inq_varid(ncid, "lat", latVarId))
+ call check(nf90_get_var(ncid, latVarId, slatsa))
+
+ call check(nf90_inq_varid(ncid, "yy", yyVarId))
+ call check(nf90_get_var(ncid, yyVarId, iya))
+
+ call check(nf90_inq_varid(ncid, "mm", mmVarId))
+ call check(nf90_get_var(ncid, mmVarId, ima))
+
+ call check(nf90_inq_varid(ncid, "dd", ddVarId))
+ call check(nf90_get_var(ncid, ddVarId, idda))
+
+ call check(nf90_inq_varid(ncid, "hh", hhVarId))
+ call check(nf90_get_var(ncid, hhVarId, ihha))
+
+ call check(nf90_inq_varid(ncid, "min", minVarId))
+ call check(nf90_get_var(ncid, minVarId, imina))
+
+ call check(nf90_inq_varid(ncid, "ss", ssVarId))
+ call check(nf90_get_var(ncid, ssVarId, iseca))
+
+ call check(nf90_inq_varid(ncid, "sza", szaVarId))
+ call check(nf90_get_var(ncid, szaVarId, sza))
+
+ call check(nf90_inq_varid(ncid, "ozone", ozoneVarId))
+ call check(nf90_get_var(ncid, ozoneVarId, ozone))
+
+ ! close the data file
+ call check(nf90_close(ncid))
+
+ ! 'Unpack' the data
+ nmrecs = 0
+ nodata = 0
+ read_loop1: do iprof = 1, nprofs
+ do ilev = 1, levs
+ if (ozone(ilev, iprof) .lt. -900.0_r_kind) cycle ! undefined
+ end do
+!!$ if (iuse_oz(ipos(ilev)) < 0) then
+!!$ usage = 10000._r_kind
+!!$ else
+!!$ usage = zero
+!!$ endif
+ nmrecs=nmrecs+levs+1
+
+ ! convert observation location to radians
+ slons0=slonsa(iprof)
+ slats0=slatsa(iprof)
+ if(abs(slats0)>90._r_kind .or. abs(slons0)>r360) cycle
+ if(slons0< zero) slons0=slons0+r360
+ if(slons0==r360) slons0=zero
+ dlat_earth_deg = slats0
+ dlon_earth_deg = slons0
+ dlat_earth = slats0 * deg2rad
+ dlon_earth = slons0 * deg2rad
+
+ if(regional)then
+ call tll2xy(dlon_earth,dlat_earth,dlon,dlat,outside)
+ if(outside) cycle
+ else
+ dlat = dlat_earth
+ dlon = dlon_earth
+ call grdcrd1(dlat,rlats,nlat,1)
+ call grdcrd1(dlon,rlons,nlon,1)
+ endif
+
+ idate5(1) = iya(iprof) !year
+ idate5(2) = ima(iprof) !month
+ idate5(3) = idda(iprof) !day
+ idate5(4) = ihha(iprof) !hour
+ idate5(5) = imina(iprof) !minute
+ call w3fs21(idate5,nmind)
+ t4dv=real((nmind-iwinbgn),r_kind)*r60inv
+ if (l4dvar.or.l4densvar) then
+ if (t4dvwinlen) then
+ write(6,*)'read_ozone: ', dtype,' obs time idate5=',idate5,', t4dv=',&
+ t4dv,' is outside time window, sstime=',sstime*r60inv
+ cycle
+ end if
+ else
+ sstime=real(nmind,r_kind)
+ tdiff=(sstime-gstime)*r60inv
+ if(abs(tdiff) > twind)then
+ write(6,*)'read_ozone: ',dtype,' obs time idate5=',idate5,', tdiff=',&
+ tdiff,' is outside time window=',twind
+ cycle
+ end if
+ end if
+
+ !! Compute total ozone
+ totoz=zero
+ do k=1,levs
+ poz(k) = ozone(k,iprof)
+ totoz=totoz+ozone(k,iprof)
+ end do
+ poz(levs+1) = totoz
+
+ !Check ozone layer values. If any layer value is bad, toss entire profile
+ do k=1,levs
+ if (poz(k)>badoz) cycle read_loop1
+ end do
+
+ ! Write ozone record to output file
+ ndata=min(ndata+1,maxobs)
+ if(ndata<=maxobs) then
+ nodata=nodata+levs+1
+ ozout(1,ndata)=rsat
+ ozout(2,ndata)=t4dv
+ ozout(3,ndata)=dlon ! grid relative longitude
+ ozout(4,ndata)=dlat ! grid relative latitude
+ ozout(5,ndata)=dlon_earth_deg ! earth relative longitude (degrees)
+ ozout(6,ndata)=dlat_earth_deg ! earth relative latitude (degrees)
+ ozout(7,ndata)=zero ! total ozone error flag
+ ozout(8,ndata)=zero ! profile ozone error flag
+ ozout(9,ndata)=sza(iprof) ! solar zenith angle
+ do k=1,levs+1
+ ozout(k+9,ndata)=poz(k)
+ end do
+ end if
+ end do read_loop1
+
+ deallocate(iya,ima,idda,ihha,imina,iseca,slatsa,slonsa, ozone, poz,sza)
+ deallocate(ipos)
+ if (ndata > maxobs) then
+ call perr('read_ozone','Number of layer obs reached maxobs = ', maxobs)
+ call perr(myname_,'Number of layer obs reached maxobs = ', maxobs)
+ call perr(myname_,' ndata = ', ndata)
+ call perr(myname_,' nodata = ', nodata)
+ call die(myname_)
+ endif
+
+ end subroutine ozlay_ncread_
!..................................................................................
subroutine check(status,stat)
diff --git a/src/gsi/m_fedNode.F90 b/src/gsi/m_fedNode.F90
new file mode 100644
index 0000000000..84a319cd12
--- /dev/null
+++ b/src/gsi/m_fedNode.F90
@@ -0,0 +1,248 @@
+module m_fedNode
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: module m_fedNode
+! prgmmr: YPW
+! org: CIMMS
+! date: 2019-09-24
+!
+! abstract: class-module of obs-type fedNode (GLM flash extent density)
+! Modified based on m_tdNode.f90
+!
+! program history log:
+! 2019-09-24 YPW - added this document block for the initial polymorphic
+! implementation.
+!
+! input argument list: see Fortran 90 style document below
+!
+! output argument list: see Fortran 90 style document below
+!
+! attributes:
+! language: Fortran 90 and/or above
+! machine:
+!
+!$$$ end subprogram documentation block
+
+! module interface:
+ use m_obsdiagNode, only: obs_diag
+ use m_obsdiagNode, only: obs_diags
+ use kinds , only: i_kind,r_kind
+ use mpeu_util, only: assert_,die,perr,warn,tell
+ use m_obsNode, only: obsNode
+
+ implicit none
+ private
+
+ public:: fedNode
+
+ type,extends(obsNode):: fedNode
+ type(obs_diag), pointer :: diags => NULL()
+ real(r_kind) :: res ! flash extent density residual
+ real(r_kind) :: err2 ! flash extent density error squared
+ real(r_kind) :: raterr2 ! square of ratio of final obs error
+ ! to original obs error
+ real(r_kind) :: b ! variational quality control parameter
+ real(r_kind) :: pg ! variational quality control parameter
+ real(r_kind) :: jb ! variational quality control parameter
+ real(r_kind) :: wij(8) ! horizontal interpolation weights
+ real(r_kind) :: fedpertb ! random number adding to the obs
+ integer(i_kind) :: k1 ! level of errtable 1-33
+ integer(i_kind) :: kx ! ob type
+ integer(i_kind) :: ij(8) ! horizontal locations
+
+ real (r_kind) :: dlev ! reference to the vertical grid
+ contains
+ procedure,nopass:: mytype
+ procedure:: setHop => obsNode_setHop_
+ procedure:: xread => obsNode_xread_
+ procedure:: xwrite => obsNode_xwrite_
+ procedure:: isvalid => obsNode_isvalid_
+ procedure:: gettlddp => gettlddp_
+
+ end type fedNode
+
+ public:: fedNode_typecast
+ public:: fedNode_nextcast
+ interface fedNode_typecast; module procedure typecast_ ; end interface
+ interface fedNode_nextcast; module procedure nextcast_ ; end interface
+
+ public:: fedNode_appendto
+ interface fedNode_appendto; module procedure appendto_ ; end interface
+
+ character(len=*),parameter:: MYNAME="m_fedNode"
+
+#include "myassert.H"
+#include "mytrace.H"
+contains
+function typecast_(aNode) result(ptr_)
+!-- cast a class(obsNode) to a type(tdNode)
+ use m_obsNode, only: obsNode
+ implicit none
+ type(fedNode),pointer:: ptr_
+ class(obsNode),pointer,intent(in):: aNode
+ ptr_ => null()
+ if(.not.associated(aNode)) return
+ select type(aNode)
+ type is(fedNode)
+ ptr_ => aNode
+ end select
+return
+end function typecast_
+
+function nextcast_(aNode) result(ptr_)
+!-- cast an obsNode_next(obsNode) to a type(fedNode)
+ use m_obsNode, only: obsNode,obsNode_next
+ implicit none
+ type(fedNode),pointer:: ptr_
+ class(obsNode),target,intent(in):: aNode
+
+ class(obsNode),pointer:: inode_
+ inode_ => obsNode_next(aNode)
+ ptr_ => typecast_(inode_)
+return
+end function nextcast_
+
+subroutine appendto_(aNode,oll)
+!-- append aNode to linked-list oLL
+ use m_obsNode , only: obsNode
+ use m_obsLList, only: obsLList,obsLList_appendNode
+ implicit none
+ type(fedNode),pointer,intent(in):: aNode
+ type(obsLList),intent(inout):: oLL
+
+ class(obsNode),pointer:: inode_
+ inode_ => aNode
+ call obsLList_appendNode(oLL,inode_)
+ inode_ => null()
+end subroutine appendto_
+
+! obsNode implementations
+
+function mytype()
+ implicit none
+ character(len=:),allocatable:: mytype
+ mytype="[fedNode]"
+end function mytype
+
+
+subroutine obsNode_xread_(aNode,iunit,istat,diagLookup,skip)
+ use m_obsdiagNode, only: obsdiagLookup_locate
+ implicit none
+ class(fedNode),intent(inout):: aNode
+ integer(i_kind),intent(in ):: iunit
+ integer(i_kind),intent( out):: istat
+ type(obs_diags),intent(in ):: diagLookup
+ logical,optional,intent(in ):: skip
+
+ character(len=*),parameter:: myname_=MYNAME//'.obsNode_xread_'
+ logical:: skip_
+_ENTRY_(myname_)
+ skip_=.false.
+ if(present(skip)) skip_=skip
+
+ istat=0
+ if(skip_) then
+ read(iunit,iostat=istat)
+ if(istat/=0) then
+ call perr(myname_,'skipping read(%(res,err2,...)), iostat =',istat)
+ _EXIT_(myname_)
+ return
+ endif
+
+ else
+ read(iunit,iostat=istat) aNode%res , &
+ aNode%err2 , &
+ aNode%raterr2 , &
+ aNode%b , &
+ aNode%pg , &
+ aNode%jb , &
+ aNode%k1 , &
+ aNode%kx , &
+ aNode%dlev , &
+ aNode%wij , &
+ aNode%ij
+ if(istat/=0) then
+ call perr(myname_,'read(%(res,err2,...), iostat =',istat)
+ _EXIT_(myname_)
+ return
+ endif
+
+ aNode%diags => obsdiagLookup_locate(diagLookup,aNode%idv,aNode%iob,1_i_kind)
+ if(.not.associated(aNode%diags)) then
+ call perr(myname_,'obsdiagLookup_locate(), %idv =',aNode%idv)
+ call perr(myname_,' %iob =',aNode%iob)
+ call die(myname_)
+ endif
+ endif
+_EXIT_(myname_)
+return
+end subroutine obsNode_xread_
+
+subroutine obsNode_xwrite_(aNode,junit,jstat)
+ implicit none
+ class(fedNode),intent(in):: aNode
+ integer(i_kind),intent(in ):: junit
+ integer(i_kind),intent( out):: jstat
+
+ character(len=*),parameter:: myname_=MYNAME//'.obsNode_xwrite_'
+_ENTRY_(myname_)
+
+ jstat=0
+ write(junit,iostat=jstat) aNode%res , &
+ aNode%err2 , &
+ aNode%raterr2 , &
+ aNode%b , &
+ aNode%pg , &
+ aNode%jb , &
+ aNode%k1 , &
+ aNode%kx , &
+ aNode%dlev , &
+ aNode%wij , &
+ aNode%ij
+ if(jstat/=0) then
+ call perr(myname_,'write(%res,err2,...), iostat =',jstat)
+ _EXIT_(myname_)
+ return
+ endif
+_EXIT_(myname_)
+return
+end subroutine obsNode_xwrite_
+
+subroutine obsNode_setHop_(aNode)
+ use m_cvgridLookup, only: cvgridLookup_getiw
+ implicit none
+ class(fedNode),intent(inout):: aNode
+
+ character(len=*),parameter:: myname_=MYNAME//'::obsNode_setHop_'
+_ENTRY_(myname_)
+ call cvgridLookup_getiw(aNode%elat,aNode%elon,aNode%dlev,aNode%ij,aNode%wij)
+_EXIT_(myname_)
+return
+end subroutine obsNode_setHop_
+
+function obsNode_isvalid_(aNode) result(isvalid_)
+ implicit none
+ logical:: isvalid_
+ class(fedNode),intent(in):: aNode
+
+ character(len=*),parameter:: myname_=MYNAME//'::obsNode_isvalid_'
+_ENTRY_(myname_)
+ isvalid_=associated(aNode%diags)
+_EXIT_(myname_)
+return
+end function obsNode_isvalid_
+
+pure subroutine gettlddp_(aNode,jiter,tlddp,nob)
+ use kinds, only: r_kind
+ implicit none
+ class(fedNode), intent(in):: aNode
+ integer(kind=i_kind),intent(in):: jiter
+ real(kind=r_kind),intent(inout):: tlddp
+ integer(kind=i_kind),optional,intent(inout):: nob
+
+ tlddp = tlddp + aNode%diags%tldepart(jiter)*aNode%diags%tldepart(jiter)
+ if(present(nob)) nob=nob+1
+return
+end subroutine gettlddp_
+
+end module m_fedNode
diff --git a/src/gsi/m_obsNodeTypeManager.F90 b/src/gsi/m_obsNodeTypeManager.F90
index b5ecc6e1ba..43b42e4bf2 100644
--- a/src/gsi/m_obsNodeTypeManager.F90
+++ b/src/gsi/m_obsNodeTypeManager.F90
@@ -70,6 +70,7 @@ module m_obsNodeTypeManager
use m_lightNode, only: lightNode
use m_dbzNode , only: dbzNode
+ use m_fedNode, only: fedNode
use kinds, only: i_kind
use m_obsNode, only: obsNode
@@ -124,6 +125,7 @@ module m_obsNodeTypeManager
public:: iobsNode_light
public:: iobsNode_dbz
+ public:: iobsNode_fed
public :: obsNode_typeMold
public :: obsNode_typeIndex
@@ -179,6 +181,7 @@ module m_obsNodeTypeManager
type( lwcpNode), target, save:: lwcp_mold
type( lightNode), target, save:: light_mold
type( dbzNode), target, save:: dbz_mold
+ type( fedNode), target, save:: fed_mold
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
character(len=*),parameter :: myname='m_obsNodeTypeManager'
@@ -245,6 +248,7 @@ module m_obsNodeTypeManager
enumerator:: iobsNode_lwcp
enumerator:: iobsNode_light
enumerator:: iobsNode_dbz
+ enumerator:: iobsNode_fed
enumerator:: iobsNode_extra_
end enum
@@ -314,6 +318,7 @@ function vname2index_(vname) result(index_)
case("light","[lightnode]"); index_ = iobsNode_light
case("dbz" , "[dbznode]"); index_ = iobsNode_dbz
+ case("fed" , "[fednode]"); index_ = iobsNode_fed
end select
end function vname2index_
@@ -377,6 +382,7 @@ function vmold2index_select_(mold) result(index_)
type is(lightNode); index_ = iobsNode_light
type is( dbzNode); index_ = iobsNode_dbz
+ type is( fedNode); index_ = iobsNode_fed
end select
end function vmold2index_select_
@@ -434,6 +440,7 @@ function index2vmold_(i_obType) result(obsmold_)
case(iobsNode_light); obsmold_ => light_mold
case(iobsNode_dbz); obsmold_ => dbz_mold
+ case(iobsNode_fed); obsmold_ => fed_mold
end select
end function index2vmold_
diff --git a/src/gsi/m_radNode.F90 b/src/gsi/m_radNode.F90
index 33070e8382..ae4854920a 100644
--- a/src/gsi/m_radNode.F90
+++ b/src/gsi/m_radNode.F90
@@ -57,6 +57,7 @@ module m_radNode
! square root of inverse of R, only used
! if using correlated obs
+ integer(i_kind),dimension(:),pointer :: iccerr => NULL()
integer(i_kind),dimension(:),pointer :: icx => NULL()
integer(i_kind),dimension(:),pointer :: ich => NULL()
integer(i_kind) :: nchan ! number of channels for this profile
@@ -214,6 +215,7 @@ subroutine obsNode_clean_(aNode)
if(associated(aNode%Rpred )) deallocate(aNode%Rpred )
if(associated(aNode%rsqrtinv)) deallocate(aNode%rsqrtinv)
if(associated(aNode%icx )) deallocate(aNode%icx )
+ if(associated(aNode%iccerr )) deallocate(aNode%iccerr )
_EXIT_(myname_)
return
end subroutine obsNode_clean_
@@ -276,6 +278,7 @@ subroutine obsNode_xread_(aNode,iunit,istat,diagLookup,skip)
if(associated(aNode%Rpred )) deallocate(aNode%Rpred)
if(associated(aNode%rsqrtinv)) deallocate(aNode%rsqrtinv)
if(associated(aNode%icx )) deallocate(aNode%icx )
+ if(associated(aNode%iccerr )) deallocate(aNode%iccerr )
nchan=aNode%nchan
allocate( aNode%diags(nchan), &
@@ -285,7 +288,7 @@ subroutine obsNode_xread_(aNode,iunit,istat,diagLookup,skip)
aNode%pred (npred,nchan), &
aNode%dtb_dvar(nsigradjac,nchan), &
aNode%ich (nchan), &
- aNode%icx (nchan) )
+ aNode%icx (nchan), aNode%iccerr(nchan) )
read(iunit,iostat=istat) aNode%ich , &
aNode%res , &
@@ -293,6 +296,7 @@ subroutine obsNode_xread_(aNode,iunit,istat,diagLookup,skip)
aNode%raterr2 , &
aNode%pred , &
aNode%icx , &
+ aNode%iccerr , &
aNode%dtb_dvar, &
aNode%wij , &
aNode%ij
@@ -368,6 +372,7 @@ subroutine obsNode_xwrite_(aNode,junit,jstat)
aNode%raterr2 , &
aNode%pred , &
aNode%icx , &
+ aNode%iccerr , &
aNode%dtb_dvar, &
aNode%wij , &
aNode%ij
diff --git a/src/gsi/m_rhs.F90 b/src/gsi/m_rhs.F90
index baee074688..aea417fe27 100644
--- a/src/gsi/m_rhs.F90
+++ b/src/gsi/m_rhs.F90
@@ -80,6 +80,7 @@ module m_rhs
public:: i_lwcp
public:: i_light
public:: i_dbz
+ public:: i_fed
public:: i_cldtot
public:: awork_size
@@ -146,6 +147,7 @@ module m_rhs
enumerator:: i_lwcp
enumerator:: i_light
enumerator:: i_dbz
+ enumerator:: i_fed
enumerator:: i_cldtot
enumerator:: i_outbound
diff --git a/src/gsi/mod_fv3_lola.f90 b/src/gsi/mod_fv3_lola.f90
index 84f8144968..11bb3b6e37 100644
--- a/src/gsi/mod_fv3_lola.f90
+++ b/src/gsi/mod_fv3_lola.f90
@@ -18,12 +18,17 @@ module mod_fv3_lola
! fv3_ll_to_h
! 2019-11-01 wu - add checks in generate_anl_grid to present the mean
! longitude correctly to fix problem near lon=0
+! 2022-03-01 X.Lu & X.Wang - add functions for HAFS dual ens capability. POC:
+! xuguang.wang@ou.edu
!
! subroutines included:
! sub generate_anl_grid
+! sub definecoef_regular_grids
! sub earthuv2fv3
! sub fv3uv2earth
+! sub fv3uv2earthens
! sub fv3_h_to_ll
+! sub fv3_h_to_ll_ens
! sub fv3_ll_to_h
! sub rotate2deg
! sub unrotate2deg
@@ -65,6 +70,9 @@ module mod_fv3_lola
public :: generate_anl_grid,fv3_h_to_ll,fv3_ll_to_h,fv3uv2earth,earthuv2fv3
public :: fv3dx,fv3dx1,fv3dy,fv3dy1,fv3ix,fv3ixp,fv3jy,fv3jyp,a3dx,a3dx1,a3dy,a3dy1,a3ix,a3ixp,a3jy,a3jyp
public :: nxa,nya,cangu,sangu,cangv,sangv,nx,ny,bilinear
+ public :: definecoef_regular_grids,fv3_h_to_ll_ens,fv3uv2earthens
+ public :: fv3dxens,fv3dx1ens,fv3dyens,fv3dy1ens,fv3ixens,fv3ixpens,fv3jyens,fv3jypens,a3dxens,a3dx1ens,a3dyens,a3dy1ens,a3ixens,a3ixpens,a3jyens,a3jypens
+ public :: nxe,nye,canguens,sanguens,cangvens,sangvens
logical bilinear
integer(i_kind) nxa,nya,nx,ny
@@ -73,6 +81,12 @@ module mod_fv3_lola
real(r_kind) ,allocatable,dimension(:,:):: a3dx,a3dx1,a3dy,a3dy1
real(r_kind) ,allocatable,dimension(:,:):: cangu,sangu,cangv,sangv
integer(i_kind),allocatable,dimension(:,:):: a3ix,a3ixp,a3jy,a3jyp
+ integer(i_kind) nxe,nye
+ real(r_kind) ,allocatable,dimension(:,:):: fv3dxens,fv3dx1ens,fv3dyens,fv3dy1ens
+ integer(i_kind),allocatable,dimension(:,:):: fv3ixens,fv3ixpens,fv3jyens,fv3jypens
+ real(r_kind) ,allocatable,dimension(:,:):: a3dxens,a3dx1ens,a3dyens,a3dy1ens
+ real(r_kind) ,allocatable,dimension(:,:):: canguens,sanguens,cangvens,sangvens
+ integer(i_kind),allocatable,dimension(:,:):: a3ixens,a3ixpens,a3jyens,a3jypens
contains
@@ -321,10 +335,10 @@ subroutine generate_anl_grid(nx,ny,grid_lon,grid_lont,grid_lat,grid_latt)
!!!! define analysis A grid !!!!!!!!!!!!!
do j=1,nxa
- xa_a(j)=(float(j-nlonh)-cx)*grid_ratio_fv3_regional
+ xa_a(j)=(real(j-nlonh,r_kind)-cx)*grid_ratio_fv3_regional
end do
do i=1,nya
- ya_a(i)=(float(i-nlath)-cy)*grid_ratio_fv3_regional
+ ya_a(i)=(real(i-nlath,r_kind)-cy)*grid_ratio_fv3_regional
end do
!!!!!compute fv3 to A grid interpolation parameters !!!!!!!!!
@@ -574,8 +588,419 @@ subroutine generate_anl_grid(nx,ny,grid_lon,grid_lont,grid_lat,grid_latt)
enddo
enddo
deallocate( xc,yc,zc,gclat,gclon,gcrlat,gcrlon)
+ deallocate(rlat_in,rlon_in)
end subroutine generate_anl_grid
+subroutine definecoef_regular_grids(nxen,nyen,grid_lon,grid_lont,grid_lat,grid_latt)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: generate_??ens_grid
+!clt modified from generate_regular_grid
+! prgmmr: parrish
+!
+! abstract: define rotated lat-lon analysis grid which is centered on fv3 tile
+! and oriented to completely cover the tile.
+!
+! program history log:
+! 2017-05-02 parrish
+! 2017-10-10 wu - 1. setup analysis A-grid,
+! 2. compute/setup FV3 to A grid interpolation parameters
+! 3. compute/setup A to FV3 grid interpolation parameters
+! 4. setup weightings for wind conversion from FV3 to earth
+! 2021-02-01 Lu & Wang - modify variable intent for HAFS dual ens. POC:
+! xuguang.wang@ou.edu
+!
+! input argument list:
+! nxen, nyen - number of cells = nxen*nyen
+! grid_lon ,grid_lat - longitudes and latitudes of fv3 grid cell corners
+! grid_lont,grid_latt - longitudes and latitudes of fv3 grid cell centers
+!
+! output argument list:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+ use kinds, only: r_kind,i_kind
+ use constants, only: quarter,one,two,half,zero,deg2rad,rearth,rad2deg
+ use gridmod, only:grid_ratio_fv3_regional
+ use mpimod, only: mype
+ use hybrid_ensemble_parameters, only: nlon_ens,nlat_ens,region_lon_ens,region_lat_ens
+ implicit none
+ real(r_kind),allocatable,dimension(:)::xbh_a,xa_a,xa_b
+ real(r_kind),allocatable,dimension(:)::ybh_a,ya_a,ya_b,yy
+ real(r_kind),allocatable,dimension(:,:)::xbh_b,ybh_b
+ real(r_kind) dlat,dlon
+
+ real(r_kind),allocatable:: region_lat_tmp(:,:),region_lon_tmp(:,:)
+ integer(i_kind), intent(in ) :: nxen,nyen ! fv3 tile x- and y-dimensions
+ real(r_kind) , intent(inout) :: grid_lon(nxen+1,nyen+1) ! fv3 cell corner longitudes
+ real(r_kind) , intent(inout) :: grid_lont(nxen,nyen) ! fv3 cell center longitudes
+ real(r_kind) , intent(inout) :: grid_lat(nxen+1,nyen+1) ! fv3 cell corner latitudes
+ real(r_kind) , intent(inout) :: grid_latt(nxen,nyen) ! fv3 cell center latitudes
+ integer(i_kind) i,j,ir,jr,n
+ real(r_kind),allocatable,dimension(:,:) :: xc,yc,zc,gclat,gclon,gcrlat,gcrlon,rlon_in,rlat_in
+ real(r_kind) xcent,ycent,zcent,rnorm,centlat,centlon
+ integer(i_kind) nxh,nyh
+ integer(i_kind) ib1,ib2,jb1,jb2,jj
+ integer (i_kind):: index0
+ integer(i_kind) nord_e2a
+ real(r_kind)gxa,gya
+
+ real(r_kind) x(nxen+1,nyen+1),y(nxen+1,nyen+1),z(nxen+1,nyen+1),xr,yr,zr,xu,yu,zu,rlat,rlon
+ real(r_kind) xv,yv,zv,vval
+ real(r_kind) uval,ewval,nsval
+
+ real(r_kind) d(4),ds
+ integer(i_kind) kk,k
+ real(r_kind) diff,sq180
+
+ nord_e2a=4
+ bilinear=.false.
+
+! create xc,yc,zc for the cell centers.
+ allocate(xc(nxen,nyen))
+ allocate(yc(nxen,nyen))
+ allocate(zc(nxen,nyen))
+ allocate(gclat(nxen,nyen))
+ allocate(gclon(nxen,nyen))
+ allocate(gcrlat(nxen,nyen))
+ allocate(gcrlon(nxen,nyen))
+ do j=1,nyen
+ do i=1,nxen
+ xc(i,j)=cos(grid_latt(i,j)*deg2rad)*cos(grid_lont(i,j)*deg2rad)
+ yc(i,j)=cos(grid_latt(i,j)*deg2rad)*sin(grid_lont(i,j)*deg2rad)
+ zc(i,j)=sin(grid_latt(i,j)*deg2rad)
+ enddo
+ enddo
+
+! compute center as average x,y,z coordinates of corners of domain --
+
+ xcent=quarter*(xc(1,1)+xc(1,nyen)+xc(nxen,1)+xc(nxen,nyen))
+ ycent=quarter*(yc(1,1)+yc(1,nyen)+yc(nxen,1)+yc(nxen,nyen))
+ zcent=quarter*(zc(1,1)+zc(1,nyen)+zc(nxen,1)+zc(nxen,nyen))
+
+ rnorm=one/sqrt(xcent**2+ycent**2+zcent**2)
+ xcent=rnorm*xcent
+ ycent=rnorm*ycent
+ zcent=rnorm*zcent
+ centlat=asin(zcent)*rad2deg
+ centlon=atan2(ycent,xcent)*rad2deg
+
+!! compute new lats, lons
+ call rotate2deg(grid_lont,grid_latt,gcrlon,gcrlat, &
+ centlon,centlat,nxen,nyen)
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!! compute analysis A-grid lats, lons
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!--------------------------obtain analysis grid dimensions nxe,nye
+ nxe=nlon_ens
+ nye=nlat_ens
+ if(mype==0) print *,'nlat,nlon=nye,nxe= ',nlat_ens,nlon_ens
+
+ allocate(rlat_in(nlat_ens,nlon_ens),rlon_in(nlat_ens,nlon_ens))
+ allocate(region_lon_tmp(nlat_ens,nlon_ens),region_lat_tmp(nlat_ens,nlon_ens))
+ region_lon_tmp=region_lon_ens*rad2deg
+ region_lat_tmp=region_lat_ens*rad2deg
+ call rotate2deg(region_lon_tmp,region_lat_tmp,rlon_in,rlat_in, &
+ centlon,centlat,nlat_ens,nlon_ens)
+
+!--------------------------obtain analysis grid spacing
+ dlat=(maxval(gcrlat)-minval(gcrlat))/(nyen-1)
+ dlon=(maxval(gcrlon)-minval(gcrlon))/(nxen-1)
+
+
+!-----setup analysis A-grid from center of the domain
+!--------------------compute all combinations of relative coordinates
+
+ allocate(xbh_a(nxen),xbh_b(nxen,nyen),xa_a(nxe),xa_b(nxe))
+ allocate(ybh_a(nyen),ybh_b(nxen,nyen),ya_a(nye),ya_b(nye))
+
+ nxh=nxen/2
+ nyh=nyen/2
+
+
+!!!!!! fv3 rotated grid; not equal spacing, non_orthogonal !!!!!!
+ do j=1,nyen
+ jr=nyen+1-j
+ do i=1,nxen
+ ir=nxen+1-i
+ xbh_b(ir,jr)=gcrlon(i,j)/dlon
+ end do
+ end do
+ do j=1,nyen
+ jr=nyen+1-j
+ do i=1,nxen
+ ir=nxen+1-i
+ ybh_b(ir,jr)=gcrlat(i,j)/dlat
+ end do
+ end do
+
+!!!! define analysis A grid !!!!!!!!!!!!!
+
+ index0=1
+ do j=1,nxe
+ xa_a(j)= rlon_in(index0,j)/dlon
+ end do
+ do i=1,nye
+ ya_a(i)= rlat_in(i,index0)/dlat
+ end do
+
+!!!!!compute fv3 to A grid interpolation parameters !!!!!!!!!
+ allocate (fv3dxens(nxe,nye),fv3dx1ens(nxe,nye),fv3dyens(nxe,nye),fv3dy1ens(nxe,nye))
+ allocate (fv3ixens(nxe,nye),fv3ixpens(nxe,nye),fv3jyens(nxe,nye),fv3jypens(nxe,nye))
+ allocate(yy(nyen))
+
+! iteration to find the fv3 grid cell
+ jb1=1
+ ib1=1
+ do j=1,nye
+ do i=1,nxe
+ do n=1,3
+ gxa=xa_a(i)
+ if(gxa < xbh_b(1,jb1))then
+ gxa= 1
+ else if(gxa > xbh_b(nxen,jb1))then
+ gxa= nxen
+ else
+ call grdcrd1(gxa,xbh_b(1,jb1),nxen,1)
+ endif
+ ib2=ib1
+ ib1=gxa
+ do jj=1,nyen
+ yy(jj)=ybh_b(ib1,jj)
+ enddo
+ gya=ya_a(j)
+ if(gya < yy(1))then
+ gya= 1
+ else if(gya > yy(nyen))then
+ gya= nyen
+ else
+ call grdcrd1(gya,yy,nyen,1)
+ endif
+ jb2=jb1
+ jb1=gya
+ if(ib1+1 > nxen)then !this block( 6 lines) is copied from GSL gsi repository
+ ib1=ib1-1
+ endif
+ if(jb1+1 > nyen)then
+ jb1=jb1-1
+ endif
+
+ if((ib1 == ib2) .and. (jb1 == jb2)) exit
+ if(n==3 ) then
+!!!!!!! if not converge, find the nearest corner point
+ d(1)=(xa_a(i)-xbh_b(ib1,jb1))**2+(ya_a(j)-ybh_b(ib1,jb1))**2
+ d(2)=(xa_a(i)-xbh_b(ib1+1,jb1))**2+(ya_a(j)-ybh_b(ib1+1,jb1))**2
+ d(3)=(xa_a(i)-xbh_b(ib1,jb1+1))**2+(ya_a(j)-ybh_b(ib1,jb1+1))**2
+ d(4)=(xa_a(i)-xbh_b(ib1+1,jb1+1))**2+(ya_a(j)-ybh_b(ib1+1,jb1+1))**2
+ kk=1
+ do k=2,4
+ if(d(k) xa_a(nxe))then
+ gxa= nxe
+ else
+ call grdcrd1(gxa,xa_a,nxe,1)
+ endif
+ a3ixens(j,i)=int(gxa)
+ a3ixens(j,i)=min(max(1,a3ixens(j,i)),nxe)
+ a3dxens(j,i)=max(zero,min(one,gxa-a3ixens(j,i)))
+ a3dx1ens(j,i)=one-a3dxens(j,i)
+ a3ixpens(j,i)=min(nxe,a3ixens(j,i)+1)
+ end do
+ end do
+
+ do i=1,nxen
+ do j=1,nyen
+ gya=ybh_b(i,j)
+ if(gya < ya_a(1))then
+ gya= 1
+ else if(gya > ya_a(nye))then
+ gya= nye
+ else
+ call grdcrd1(gya,ya_a,nye,1)
+ endif
+ a3jyens(j,i)=int(gya)
+ a3jyens(j,i)=min(max(1,a3jyens(j,i)),nye)
+ a3dyens(j,i)=max(zero,min(one,gya-a3jyens(j,i)))
+ a3dy1ens(j,i)=one-a3dyens(j,i)
+ a3jypens(j,i)=min(nye,a3jyens(j,i)+1)
+ end do
+ end do
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!! find coefficients for wind conversion btw FV3 & earth
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ allocate (canguens(nxen,nyen+1),sanguens(nxen,nyen+1),cangvens(nxen+1,nyen),sangvens(nxen+1,nyen))
+
+! 1. compute x,y,z at cell cornor from grid_lon, grid_lat
+
+ do j=1,nyen+1
+ do i=1,nxen+1
+ x(i,j)=cos(grid_lat(i,j)*deg2rad)*cos(grid_lon(i,j)*deg2rad)
+ y(i,j)=cos(grid_lat(i,j)*deg2rad)*sin(grid_lon(i,j)*deg2rad)
+ z(i,j)=sin(grid_lat(i,j)*deg2rad)
+ enddo
+ enddo
+
+! 2 find angles to E-W and N-S for U edges
+
+ sq180=180._r_kind**2
+ do j=1,nyen+1
+ do i=1,nxen
+! center lat/lon of the edge
+ rlat=half*(grid_lat(i,j)+grid_lat(i+1,j))
+ diff=(grid_lon(i,j)-grid_lon(i+1,j))**2
+ if(diff < sq180)then
+ rlon=half*(grid_lon(i,j)+grid_lon(i+1,j))
+ else
+ rlon=half*(grid_lon(i,j)+grid_lon(i+1,j)-360._r_kind)
+ endif
+! vector to center of the edge
+ xr=cos(rlat*deg2rad)*cos(rlon*deg2rad)
+ yr=cos(rlat*deg2rad)*sin(rlon*deg2rad)
+ zr=sin(rlat*deg2rad)
+! vector of the edge
+ xu= x(i+1,j)-x(i,j)
+ yu= y(i+1,j)-y(i,j)
+ zu= z(i+1,j)-z(i,j)
+! find angle with cross product
+ uval=sqrt((xu**2+yu**2+zu**2))
+ ewval=sqrt((xr**2+yr**2))
+ nsval=sqrt((xr*zr)**2+(zr*yr)**2+(xr*xr+yr*yr)**2)
+ canguens(i,j)=(-yr*xu+xr*yu)/ewval/uval
+ sanguens(i,j)=(-xr*zr*xu-zr*yr*yu+(xr*xr+yr*yr)*zu) / nsval/uval
+ enddo
+ enddo
+
+! 3 find angles to E-W and N-S for V edges
+ do j=1,nyen
+ do i=1,nxen+1
+ rlat=half*(grid_lat(i,j)+grid_lat(i,j+1))
+ diff=(grid_lon(i,j)-grid_lon(i,j+1))**2
+ if(diff < sq180)then
+ rlon=half*(grid_lon(i,j)+grid_lon(i,j+1))
+ else
+ rlon=half*(grid_lon(i,j)+grid_lon(i,j+1)-360._r_kind)
+ endif
+ xr=cos(rlat*deg2rad)*cos(rlon*deg2rad)
+ yr=cos(rlat*deg2rad)*sin(rlon*deg2rad)
+ zr=sin(rlat*deg2rad)
+ xv= x(i,j+1)-x(i,j)
+ yv= y(i,j+1)-y(i,j)
+ zv= z(i,j+1)-z(i,j)
+ vval=sqrt((xv**2+yv**2+zv**2))
+ ewval=sqrt((xr**2+yr**2))
+ nsval=sqrt((xr*zr)**2+(zr*yr)**2+(xr*xr+yr*yr)**2)
+ cangvens(i,j)=(-yr*xv+xr*yv)/ewval/vval
+ sangvens(i,j)=(-xr*zr*xv-zr*yr*yv+(xr*xr+yr*yr)*zv) / nsval/vval
+ enddo
+ enddo
+ deallocate( xc,yc,zc,gclat,gclon,gcrlat,gcrlon)
+ deallocate(rlat_in,rlon_in)
+end subroutine definecoef_regular_grids
+
subroutine earthuv2fv3(u,v,nx,ny,u_out,v_out)
!$$$ subprogram documentation block
! . . . .
@@ -679,6 +1104,51 @@ subroutine fv3uv2earth(u,v,nx,ny,u_out,v_out)
return
end subroutine fv3uv2earth
+subroutine fv3uv2earthens(u,v,nxen,nyen,u_out,v_out)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: fv3uv2earthens
+! prgmmr: wu 2017-06-15
+!
+! abstract: project fv3 UV to earth UV and interpolate to the center of the
+! cells
+!
+! program history log:
+!
+!
+! input argument list:
+! u,v - fv3 winds on the cell boundaries
+! nx,ny - dimensions
+!
+! output argument list:
+! u_out,v_out - output earth wind components at center of the cell
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+ use kinds, only: r_kind,i_kind
+ use constants, only: half
+ implicit none
+
+ integer(i_kind), intent(in ) :: nxen,nyen ! fv3 tile x- and y-dimensions
+ real(r_kind),intent(in ) :: u(nxen,nyen+1),v(nxen+1,nyen)
+ real(r_kind),intent( out) :: u_out(nxen,nyen),v_out(nxen,nyen)
+ integer(i_kind) i,j
+
+ do j=1,nyen
+ do i=1,nxen
+ u_out(i,j)=half *((u(i,j)*sangvens(i,j)-v(i,j)*sanguens(i,j))/(canguens(i,j)*sangvens(i,j)-sanguens(i,j)*cangvens(i,j)) &
+ +(u(i,j+1)*sangvens(i+1,j)-v(i+1,j)*sanguens(i,j+1))/(canguens(i,j+1)*sangvens(i+1,j)-sanguens(i,j+1)*cangvens(i+1,j)))
+ v_out(i,j)=half *((u(i,j)*cangvens(i,j)-v(i,j)*canguens(i,j))/(sanguens(i,j)*cangvens(i,j)-canguens(i,j)*sangvens(i,j)) &
+ +(u(i,j+1)*cangvens(i+1,j)-v(i+1,j)*canguens(i,j+1))/(sanguens(i,j+1)*cangvens(i+1,j)-canguens(i,j+1)*sangvens(i+1,j)))
+ end do
+ end do
+ return
+end subroutine fv3uv2earthens
+
subroutine fv3_h_to_ll(b_in,a,nb,mb,na,ma,rev_flg)
!$$$ subprogram documentation block
! . . . .
@@ -753,6 +1223,85 @@ subroutine fv3_h_to_ll(b_in,a,nb,mb,na,ma,rev_flg)
return
end subroutine fv3_h_to_ll
+subroutine fv3_h_to_ll_ens(b_in,a,nb,mb,na,ma,rev_flg)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: fv3_h_to_ll
+! prgmmr: wu 2017-05-30
+!
+! abstract: interpolate from rotated fv3 grid to A grid.
+! Interpolation choices 1)bilinear both ways
+! 2)inverse-distance weighting average
+! reverse E-W and N-S directions & reverse i,j for output array a(nlat,nlon)
+!
+! program history log:
+!
+!
+! input argument list:
+! mb,nb - fv3 dimensions
+! ma,na - a dimensions
+! b - input variable b
+! xb,yb - b array x and y coordinates
+! xa,ya - a array coordinates (xa in xb units, ya in yb units)
+!
+! output argument list:
+! a - output interpolated array
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+ use constants, only: zero,one
+ implicit none
+
+ integer(i_kind),intent(in ) :: mb,nb,ma,na
+ real(r_kind) ,intent(in ) :: b_in(nb,mb)
+ logical ,intent(in ) :: rev_flg
+ real(r_kind) ,intent( out) :: a(ma,na)
+
+ integer(i_kind) i,j,ir,jr,mbp,nbp
+ real(r_kind) b(nb,mb)
+
+ mbp=mb+1
+ nbp=nb+1
+ bilinear=.false.
+ if(rev_flg) then
+!!!!!!!!! reverse E-W and N-S
+ do j=1,mb
+ jr=mbp-j
+ do i=1,nb
+ ir=nbp-i
+ b(ir,jr)=b_in(i,j)
+ end do
+ end do
+ else
+ b(:,:)=b_in(:,:)
+ endif
+!!!!!!!!! interpolate to A grid & reverse ij for array a(lat,lon)
+ if(bilinear)then ! bilinear interpolation
+ do j=1,ma
+ do i=1,na
+ a(j,i)=fv3dx1ens(i,j)*(fv3dy1ens(i,j)*b(fv3ixens(i,j),fv3jyens(i,j)) &
+ +fv3dyens(i,j)*b(fv3ixens(i,j),fv3jypens(i,j))) &
+ +fv3dxens(i,j)*(fv3dy1ens(i,j)*b(fv3ixpens(i,j),fv3jyens(i,j)) &
+ +fv3dyens(i,j)*b(fv3ixpens(i,j),fv3jypens(i,j)))
+ end do
+ end do
+ else ! inverse-distance weighting average
+ do j=1,ma
+ do i=1,na
+ a(j,i)=fv3dxens(i,j)*b(fv3ixens(i,j),fv3jyens(i,j)) &
+ +fv3dyens(i,j)*b(fv3ixens(i,j),fv3jypens(i,j)) &
+ +fv3dx1ens(i,j)*b(fv3ixpens(i,j),fv3jyens(i,j)) &
+ +fv3dy1ens(i,j)*b(fv3ixpens(i,j),fv3jypens(i,j))
+ end do
+ end do
+ endif
+
+ return
+end subroutine fv3_h_to_ll_ens
+
subroutine fv3_ll_to_h(a,b,nxa,nya,nxb,nyb,rev_flg)
!$$$ subprogram documentation block
! . . . .
diff --git a/src/gsi/mod_vtrans.f90 b/src/gsi/mod_vtrans.f90
index 3c7d8af8f4..f9538e0735 100644
--- a/src/gsi/mod_vtrans.f90
+++ b/src/gsi/mod_vtrans.f90
@@ -269,7 +269,7 @@ subroutine create_vtrans(mype)
! count:
! Not clear if area weighting would be better.
- count=one/float(nlat*nlon)
+ count=one/real(nlat*nlon,r_kind)
ier=0
call gsi_bundlegetpointer (gsi_metguess_bundle(ntguessig),'ps',ges_ps_nt, istatus)
diff --git a/src/gsi/mod_wrfmass_to_a.f90 b/src/gsi/mod_wrfmass_to_a.f90
index 716ff37f77..594f128709 100644
--- a/src/gsi/mod_wrfmass_to_a.f90
+++ b/src/gsi/mod_wrfmass_to_a.f90
@@ -312,7 +312,7 @@ subroutine wrfmass_obs_to_a8(obsba,nreal,maxobs,ilat,ilon,numobs)
i=int(ria(n)+0.5_r_kind)
j=int(rja(n)+0.5_r_kind)
- adist=(ria(n)-float(i))*(ria(n)-float(i))+(rja(n)-float(j))*(rja(n)-float(j))
+ adist=(ria(n)-real(i,r_kind))**2+(rja(n)-real(j,r_kind))**2
if(adist < dist(i,j)) then
dist(i,j)=adist
ija(i,j)=n
@@ -324,8 +324,8 @@ subroutine wrfmass_obs_to_a8(obsba,nreal,maxobs,ilat,ilon,numobs)
do i=1,nxa
if(ija(i,j) > 0) then
n=n+1
- obsba(ilon,n)=float(i)
- obsba(ilat,n)=float(j)
+ obsba(ilon,n)=real(i,r_kind)
+ obsba(ilat,n)=real(j,r_kind)
do k=3,nreal
obsba(k,n)=obsa(k,ija(i,j))
enddo
diff --git a/src/gsi/mp_compact_diffs_mod1.f90 b/src/gsi/mp_compact_diffs_mod1.f90
index bb924441b7..292986a56a 100644
--- a/src/gsi/mp_compact_diffs_mod1.f90
+++ b/src/gsi/mp_compact_diffs_mod1.f90
@@ -1550,8 +1550,8 @@ subroutine mp_compact_dlon(b,dbdx,vector)
polu=polu+grid3(ix)*coslon(ix)
polv=polv+grid3(ix)*sinlon(ix)
end do
- polu=polu/float(nlon)
- polv=polv/float(nlon)
+ polu=polu/real(nlon,r_kind)
+ polv=polv/real(nlon,r_kind)
do ix=1,nlon
grid3pol(ix)=polu*coslon(ix)+polv*sinlon(ix)
end do
@@ -1673,8 +1673,8 @@ subroutine mp_compact_dlon_ad(b,dbdx,vector)
polu=polu+grid3pol(ix)*coslon(ix)
polv=polv+grid3pol(ix)*sinlon(ix)
end do
- polu=polu/float(nlon)
- polv=polv/float(nlon)
+ polu=polu/real(nlon,r_kind)
+ polv=polv/real(nlon,r_kind)
do ix=1,nlon
grid3(ix)=grid3(ix)+polu*coslon(ix)+polv*sinlon(ix)
end do
@@ -1977,8 +1977,8 @@ subroutine mp_uv_pole(u,v)
polsu=polsu+u(2,ix,k)*coslon(ix)+v(2,ix,k)*sinlon(ix)
polsv=polsv+u(2,ix,k)*sinlon(ix)-v(2,ix,k)*coslon(ix)
end do
- polsu=polsu/float(nlon)
- polsv=polsv/float(nlon)
+ polsu=polsu/real(nlon,r_kind)
+ polsv=polsv/real(nlon,r_kind)
do ix=1,nlon
u(1,ix,k)=polsu*coslon(ix)+polsv*sinlon(ix)
v(1,ix,k)=polsu*sinlon(ix)-polsv*coslon(ix)
@@ -1993,8 +1993,8 @@ subroutine mp_uv_pole(u,v)
polnu=polnu+u(1,ix,k)*coslon(ix)-v(1,ix,k)*sinlon(ix)
polnv=polnv+u(1,ix,k)*sinlon(ix)+v(1,ix,k)*coslon(ix)
end do
- polnu=polnu/float(nlon)
- polnv=polnv/float(nlon)
+ polnu=polnu/real(nlon,r_kind)
+ polnv=polnv/real(nlon,r_kind)
do ix=1,nlon
u(2,ix,k)= polnu*coslon(ix)+polnv*sinlon(ix)
v(2,ix,k)=-polnu*sinlon(ix)+polnv*coslon(ix)
@@ -2055,8 +2055,8 @@ subroutine mp_uv_pole_ad(u,v)
u(1,ix,k)=zero
v(1,ix,k)=zero
end do
- polsu=polsu/float(nlon)
- polsv=polsv/float(nlon)
+ polsu=polsu/real(nlon,r_kind)
+ polsv=polsv/real(nlon,r_kind)
do ix=1,nlon
u(2,ix,k)=u(2,ix,k)+polsu*coslon(ix)+polsv*sinlon(ix)
v(2,ix,k)=v(2,ix,k)+polsu*sinlon(ix)-polsv*coslon(ix)
@@ -2073,8 +2073,8 @@ subroutine mp_uv_pole_ad(u,v)
u(2,ix,k)=zero
v(2,ix,k)=zero
end do
- polnu=polnu/float(nlon)
- polnv=polnv/float(nlon)
+ polnu=polnu/real(nlon,r_kind)
+ polnv=polnv/real(nlon,r_kind)
do ix=1,nlon
u(1,ix,k)=u(1,ix,k)+polnu*coslon(ix)+polnv*sinlon(ix)
v(1,ix,k)=v(1,ix,k)-polnu*sinlon(ix)+polnv*coslon(ix)
diff --git a/src/gsi/mpeu_util.F90 b/src/gsi/mpeu_util.F90
index 960af8b71a..76271a4770 100644
--- a/src/gsi/mpeu_util.F90
+++ b/src/gsi/mpeu_util.F90
@@ -553,22 +553,6 @@ subroutine close_if_(fname,stat)
endif
end subroutine close_if_
-#ifdef _NEW_CODE_
-!! need to send outputs to variables.
-!! need to set return code (stat=).
-subroutine ls_(files) ! show information? or just inquire(exists(file))
- call system("ls "//files)
-end subroutine ls_
-subroutine rm_(files) ! delete, open();close(status='delete')
- call system("rm "//files)
-end subroutine rm_
-subroutine mkdir_(dir,mode,parents)
- call system("mkdir "//files)
-end subroutine mkdir_
-subroutine size_(file) ! faster access?
- call system("wc -c "//files)
-end subroutine size_
-#endif
#endif
function myid_(who)
diff --git a/src/gsi/ncepgfs_ghg.f90 b/src/gsi/ncepgfs_ghg.f90
index 6c5fa7bb9d..9b34d8aa6e 100644
--- a/src/gsi/ncepgfs_ghg.f90
+++ b/src/gsi/ncepgfs_ghg.f90
@@ -326,7 +326,7 @@ subroutine read_gfsco2 &
do i=1,nmxlon
co2diff= co2_sav2(i,j,k)-co2_sav1(i,j,k)
co2rate= co2diff/ndmax
- co2_Tintrp(i,j,k)= co2_sav1(i,j,k)+ co2rate*float(idd-1)
+ co2_Tintrp(i,j,k)= co2_sav1(i,j,k)+ co2rate*real(idd-1,r_kind)
enddo
enddo
enddo
@@ -558,7 +558,7 @@ subroutine read_ch4n2oco &
do i=1,nmaxlon
ghgdiff= ghg_sav2(1,j,k)-ghg_sav1(1,j,k)
ghgrate= ghgdiff/ndmax
- ghg_Tintrp(1,j,k)= ghg_sav1(1,j,k)+ ghgrate*float(idd-1)
+ ghg_Tintrp(1,j,k)= ghg_sav1(1,j,k)+ ghgrate*real(idd-1,r_kind)
enddo
enddo
enddo
diff --git a/src/gsi/ncepgfs_io.f90 b/src/gsi/ncepgfs_io.f90
index 52dcc4e1b5..dd46916039 100644
--- a/src/gsi/ncepgfs_io.f90
+++ b/src/gsi/ncepgfs_io.f90
@@ -1440,7 +1440,7 @@ subroutine write_gfs(increment,mype_atm,mype_sfc)
if ( use_gfs_nemsio ) then
if ( write_fv3_incr ) then
- call write_fv3_increment(grd_a,sp_a,filename,mype_atm, &
+ call write_fv3_increment(grd_a,filename,mype_atm, &
atm_bundle,itoutsig)
else
if (fv3_full_hydro) then
@@ -1461,7 +1461,7 @@ subroutine write_gfs(increment,mype_atm,mype_sfc)
else if ( use_gfs_ncio ) then
if ( write_fv3_incr ) then
- call write_fv3_increment(grd_a,sp_a,filename,mype_atm, &
+ call write_fv3_increment(grd_a,filename,mype_atm, &
atm_bundle,itoutsig)
else
call write_gfsncatm(grd_a,sp_a,filename,mype_atm, &
@@ -2640,9 +2640,9 @@ subroutine write_ens_sfc_nst(mype_so,dsfct)
allocate(slatx(jmax),wlatx(jmax))
allocate(rlats_ens_sfc(nlat_ens_sfc),rlons_ens_sfc(nlon_ens_sfc))
call splat(4,jmax,slatx,wlatx)
- dlon=two*pi/float(nlon_ens_sfc)
+ dlon=two*pi/real(nlon_ens_sfc,r_kind)
do i=1,nlon_ens_sfc
- rlons_ens_sfc(i)=float(i-1)*dlon
+ rlons_ens_sfc(i)=real(i-1,r_kind)*dlon
end do
do i=1,(nlat_ens_sfc-1)/2
rlats_ens_sfc(i+1)=-asin(slatx(i))
@@ -3074,9 +3074,9 @@ subroutine write_ens_dsfct(mype_so,dsfct)
allocate(slatx(jmax),wlatx(jmax))
allocate(rlats_ens_sfc(nlat_ens_sfc),rlons_ens_sfc(nlon_ens_sfc))
call splat(4,jmax,slatx,wlatx)
- dlon=two*pi/float(nlon_ens_sfc)
+ dlon=two*pi/real(nlon_ens_sfc,r_kind)
do i=1,nlon_ens_sfc
- rlons_ens_sfc(i)=float(i-1)*dlon
+ rlons_ens_sfc(i)=real(i-1,r_kind)*dlon
end do
do i=1,(nlat_ens_sfc-1)/2
rlats_ens_sfc(i+1)=-asin(slatx(i))
@@ -3247,7 +3247,7 @@ subroutine glbave(fld,ave)
enddo
enddo
enddo
- xave=xave/(two_quad*float(nlon))
+ xave=xave/(two_quad*real(nlon,r_quad))
call mpl_allreduce(size(ave,1),qpvals=xave)
ave=xave
deallocate(xave)
diff --git a/src/gsi/ncepnems_io.f90 b/src/gsi/ncepnems_io.f90
index 73f06ffd07..595f07e152 100755
--- a/src/gsi/ncepnems_io.f90
+++ b/src/gsi/ncepnems_io.f90
@@ -82,7 +82,8 @@ module ncepnems_io
! nfsecondn FCST Secs (i_kind) numerator
! nfsecondd FCST Secs (i_kind) denominator
!
-! %fhour = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+! %fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+! real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
!
! nframe - nframe is the number of grids extend outward from the
! edge of modeling domain.
@@ -835,7 +836,8 @@ subroutine read_atm_ (grd,filename,sp_a,uvflag,vordivflag,zflag, &
call stop2(101)
end if
- fhour = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
odate(3) = idate(3) !day
@@ -1300,7 +1302,8 @@ subroutine read_sfc_(sfct,soil_moi,sno,soil_temp,veg_frac,fact10,sfc_rough, &
call stop2(102)
end if
- fhour = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
odate(3) = idate(3) !day
@@ -1699,7 +1702,8 @@ subroutine read_sfc_anl_(isli_anl)
call stop2(102)
end if
- fhour = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
odate(3) = idate(3) !day
@@ -2029,7 +2033,8 @@ subroutine read_nst_ (tref,dt_cool,z_c,dt_warm,z_w,c_0,c_d,w_0,w_d)
call stop2(istop)
end if
- fhour = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
odate(1) = idate(4) !hour
odate(2) = idate(2) !month
odate(3) = idate(3) !day
@@ -5469,8 +5474,8 @@ subroutine tran_gfssfc(ain,aout,lonb,latb)
sumn = ain(i,1) + sumn
sums = ain(i,latb) + sums
end do
- sumn = sumn/float(lonb)
- sums = sums/float(lonb)
+ sumn = sumn/real(lonb,r_kind)
+ sums = sums/real(lonb,r_kind)
! Transfer from local work array to surface guess array
do j = 1,lonb
aout(1,j)=sums
diff --git a/src/gsi/netcdfgfs_io.f90 b/src/gsi/netcdfgfs_io.f90
index ce32e13554..8aa6c4cc6a 100644
--- a/src/gsi/netcdfgfs_io.f90
+++ b/src/gsi/netcdfgfs_io.f90
@@ -105,6 +105,7 @@ subroutine read_
!
! program history log:
! 2019-09-24 Martin - create routine based on read_nems
+! 2022-03-23 Draper - add option to include T2m and q2m in MetGuess
!
! input argument list:
!
@@ -129,6 +130,7 @@ subroutine read_
use general_sub2grid_mod, only: sub2grid_info,general_sub2grid_create_info,general_sub2grid_destroy_info
use mpimod, only: npe,mype
use cloud_efr_mod, only: cloud_calc_gfs,set_cloud_lower_bound
+ use jfunc, only: hofx_2m_sfcfile
use gridmod, only: fv3_full_hydro
implicit none
@@ -141,6 +143,8 @@ subroutine read_
real(r_kind),pointer,dimension(:,: ):: ges_ps_it =>NULL()
real(r_kind),pointer,dimension(:,: ):: ges_z_it =>NULL()
+ real(r_kind),pointer,dimension(:,: ):: ges_t2m_it =>NULL()
+ real(r_kind),pointer,dimension(:,: ):: ges_q2m_it =>NULL()
real(r_kind),pointer,dimension(:,:,:):: ges_u_it =>NULL()
real(r_kind),pointer,dimension(:,:,:):: ges_v_it =>NULL()
real(r_kind),pointer,dimension(:,:,:):: ges_div_it =>NULL()
@@ -164,8 +168,10 @@ subroutine read_
type(gsi_grid) :: atm_grid
integer(i_kind),parameter :: n2d=2
! integer(i_kind),parameter :: n3d=8
+ integer(i_kind),parameter :: n2d_2m=4
integer(i_kind),parameter :: n3d=14
character(len=4), parameter :: vars2d(n2d) = (/ 'z ', 'ps ' /)
+ character(len=4), parameter :: vars2d_with2m(n2d_2m) = (/ 'z ', 'ps ','t2m ','q2m ' /)
! character(len=4), parameter :: vars3d(n3d) = (/ 'u ', 'v ', &
! 'vor ', 'div ', &
! 'tv ', 'q ', &
@@ -189,8 +195,11 @@ subroutine read_
! Allocate bundle used for reading members
call gsi_gridcreate(atm_grid,lat2,lon2,nsig)
-
- call gsi_bundlecreate(atm_bundle,atm_grid,'aux-atm-read',istatus,names2d=vars2d,names3d=vars3d)
+ if (hofx_2m_sfcfile) then
+ call gsi_bundlecreate(atm_bundle,atm_grid,'aux-atm-read',istatus,names2d=vars2d_with2m,names3d=vars3d)
+ else
+ call gsi_bundlecreate(atm_bundle,atm_grid,'aux-atm-read',istatus,names2d=vars2d,names3d=vars3d)
+ endif
if(istatus/=0) then
write(6,*) myname_,': trouble creating atm_bundle'
call stop2(999)
@@ -198,9 +207,15 @@ subroutine read_
do it=1,nfldsig
- write(filename,'(''sigf'',i2.2)') ifilesig(it)
-
! Read background fields into bundle
+ if (hofx_2m_sfcfile) then
+ if (mype==0) write(*,*) 'calling general_read_gfsatm_nc for 2m data', it
+ write(filename,'(''sfcf'',i2.2)') ifilesig(it)
+ call general_read_gfsatm_nc(grd_t,sp_a,filename,.true.,.true.,.true.,&
+ atm_bundle,.true.,istatus)
+ if (mype==0) write(*,*) 'done with general_read_gfsatm_nc for 2m data', it
+ end if
+ write(filename,'(''sigf'',i2.2)') ifilesig(it)
if (fv3_full_hydro) then
if (mype==0) write(*,*) 'calling general_read_gfsatm_allhydro_nc', it
call general_read_gfsatm_allhydro_nc(grd_t,sp_a,filename,.true.,.true.,.true.,&
@@ -273,6 +288,16 @@ subroutine set_guess_
call gsi_bundlegetpointer (gsi_metguess_bundle(it),'z' ,ges_z_it ,istatus)
if(istatus==0) ges_z_it = ptr2d
endif
+ call gsi_bundlegetpointer (atm_bundle,'t2m',ptr2d,istatus)
+ if (istatus==0) then
+ call gsi_bundlegetpointer (gsi_metguess_bundle(it),'t2m' ,ges_t2m_it ,istatus)
+ if(istatus==0) ges_t2m_it = ptr2d
+ endif
+ call gsi_bundlegetpointer (atm_bundle,'q2m',ptr2d,istatus)
+ if (istatus==0) then
+ call gsi_bundlegetpointer (gsi_metguess_bundle(it),'q2m' ,ges_q2m_it ,istatus)
+ if(istatus==0) ges_q2m_it = ptr2d
+ endif
call gsi_bundlegetpointer (atm_bundle,'u',ptr3d,istatus)
if (istatus==0) then
call gsi_bundlegetpointer (gsi_metguess_bundle(it),'u' ,ges_u_it ,istatus)
@@ -1300,7 +1325,7 @@ subroutine read_sfc_anl_(isli_anl)
! open the netCDF file
sfcges = open_dataset(filename,errcode=iret)
if (iret/=0) then
- write(6,*) trim(my_name),': ***ERROR*** ',trim(filename),' NOT AVAILABLE: PROGRAM STOPS'
+ write(6,*) trim(my_name),': ***FATAL ERROR*** ',trim(filename),' NOT AVAILABLE: PROGRAM STOPS'
call stop2(999)
endif
@@ -3177,8 +3202,8 @@ subroutine tran_gfsncsfc(ain,aout,lonb,latb)
sumn = ain(i,1) + sumn
sums = ain(i,latb) + sums
end do
- sumn = sumn/float(lonb)
- sums = sums/float(lonb)
+ sumn = sumn/real(lonb,r_kind)
+ sums = sums/real(lonb,r_kind)
! Transfer from local work array to surface guess array
do j = 1,lonb
aout(1,j)=sums
diff --git a/src/gsi/nlmsas_ad.f90 b/src/gsi/nlmsas_ad.f90
index be8213b340..7ad413aa6b 100644
--- a/src/gsi/nlmsas_ad.f90
+++ b/src/gsi/nlmsas_ad.f90
@@ -707,10 +707,10 @@ subroutine nlmsas_ad_im_ix_(im,ix,km,jcap,delt,del,sl,rcs,&
pdpdwn = zero
pdetrn = 200._r_kind
xlambu = 1.e-4_r_kind
- fjcap = (float(jcap) / 126._r_kind) ** 2
+ fjcap = (real(jcap,r_kind) / 126._r_kind) ** 2
val = one
fjcap = max(fjcap,val)
- fkm = (float(km) / 28._r_kind) ** 2
+ fkm = (real(km,r_kind) / 28._r_kind) ** 2
fkm = max(fkm,one)
w1l = -8.e-3_r_kind
w2l = -4.e-2_r_kind
@@ -1058,7 +1058,7 @@ subroutine nlmsas_ad_im_ix_(im,ix,km,jcap,delt,del,sl,rcs,&
! Select cloud from ensemble
do i=1,im
- kt2(i) = nint(xkt2(i)*float(ktcon(i)-jmin(i))-half) + jmin(i) + 1
+ kt2(i) = nint(xkt2(i)*real(ktcon(i)-jmin(i),r_kind)-half) + jmin(i) + 1
tem1 = hcko(jmin(i),i) - hesol(kt2(i),i)
tem2 = sumz(kt2(i),i) * hesol(kt2(i),i) - sumh(kt2(i),i)
if (abs(tem2) > 0.000001_r_kind) then
diff --git a/src/gsi/obs_para.f90 b/src/gsi/obs_para.f90
index 530e946be6..869efa5e78 100644
--- a/src/gsi/obs_para.f90
+++ b/src/gsi/obs_para.f90
@@ -41,11 +41,10 @@ subroutine obs_para(ndata,mype)
! grid.
!
! input argument list:
-! ndata(*,1)- number of prefiles retained for further processing
+! ndata(*,1)- number of profiles retained for further processing
! ndata(*,2)- number of observations read
! ndata(*,3)- number of observations keep after read
! mype - mpi task number
-! ipoint - pointer in array containing information about all obs type to process
!
! output argument list:
!
@@ -342,7 +341,8 @@ subroutine count_obs(ndata,nn_obs,lat_data,lon_data,obs_data,nobs_s)
integer(i_kind) ,intent(in ) :: ndata,lat_data,lon_data
integer(i_kind) ,intent(in ) :: nn_obs
integer(i_kind),dimension(npe),intent(inout) :: nobs_s
- real(r_kind),dimension(nn_obs,ndata),intent(in) :: obs_data
+ real(r_kind),dimension(nn_obs,*),intent(in) :: obs_data
+! real(r_kind),dimension(nn_obs,ndata),intent(in) :: obs_data
! Declare local variables
integer(i_kind) lon,lat,n,k
diff --git a/src/gsi/obs_sensitivity.f90 b/src/gsi/obs_sensitivity.f90
index 880ee6384a..8e5a87010f 100644
--- a/src/gsi/obs_sensitivity.f90
+++ b/src/gsi/obs_sensitivity.f90
@@ -61,6 +61,8 @@ module obs_sensitivity
use hybrid_ensemble_isotropic, only: create_ensemble,load_ensemble,destroy_ensemble
use hybrid_ensemble_isotropic, only: hybens_localization_setup
use mpeu_util, only: perr,die
+use control2state_mod, only: control2state,control2state_ad
+use ensctl2state_mod, only: ensctl2state,ensctl2state_ad
! ------------------------------------------------------------------------------
implicit none
save
diff --git a/src/gsi/observer.F90 b/src/gsi/observer.F90
index 00f51448ac..52920630a4 100644
--- a/src/gsi/observer.F90
+++ b/src/gsi/observer.F90
@@ -49,8 +49,6 @@ module observermod
use gsi_4dvar, only: l4dvar
use convinfo, only: convinfo_destroy
use m_gsiBiases, only : create_bkgbias_grids, destroy_bkgbias_grids
- use m_berror_stats, only: berror_get_dims
- use m_berror_stats_reg, only: berror_get_dims_reg
use timermod, only: timer_ini, timer_fnl
use read_obsmod, only: read_obs
use lag_fields, only: lag_guessini
diff --git a/src/gsi/obsmod.F90 b/src/gsi/obsmod.F90
index 1fb03d0940..1c45c62bc8 100644
--- a/src/gsi/obsmod.F90
+++ b/src/gsi/obsmod.F90
@@ -160,6 +160,8 @@ module obsmod
! 2021-11-16 Zhao - add option l_obsprvdiag (if true) to trigger the output of
! observation provider and sub-provider information into
! obsdiags files (used for AutoObsQC)
+! 2023-07-10 Y. Wang, D. Dowell - add variables for flash extent density
+! 2023-10-10 H. Wang (GSL) - add variables for flash extent density EnVar DA
!
! Subroutines Included:
! sub init_obsmod_dflts - initialize obs related variables to default values
@@ -186,6 +188,13 @@ module obsmod
! def write_diag - namelist logical array to compute/write (=true) diag files
! def diag_radardbz- namelist logical to compute/write (=true) radar
! reflectiivty diag files
+! def diag_fed - namelist logical to compute/write (=true) flash extent density diag files
+! def innov_use_model_fed - namelist logical. True: use (the FEB in background to calculate innovation
+! False: calculate innvation use
+! the obs operator in GSI
+! def if_model_fed - namelist logical. True: Read in FED from background
+! including from ensemble.
+! def r_hgt_fed - height of fed observations
! def reduce_diag - namelist logical to produce reduced radiance diagnostic files
! def use_limit - parameter set equal to -1 if diag files produced or 0 if not diag files or reduce_diag
! def obs_setup - prefix for files passing pe relative obs data to setup routines
@@ -434,9 +443,10 @@ module obsmod
public :: ran01dom,dval_use
public :: iout_pcp,iout_rad,iadate,iadatemn,write_diag,reduce_diag,oberrflg,bflag,ndat,dthin,dmesh,l_do_adjoint
public :: diag_radardbz
+ public :: diag_fed
public :: lsaveobsens
- public :: iout_cldch, mype_cldch
- public :: nprof_gps,time_offset,ianldate,tcp_box
+ public :: iout_cldch, mype_cldch
+ public :: nprof_gps,time_offset,ianldate,tcp_box
public :: iout_oz,iout_co,dsis,ref_obs,obsfile_all,lobserver,tcp_posmatch,perturb_obs,ditype,dsfcalc,dplat
public :: time_window,dval,dtype,dfile,dirname,obs_setup,oberror_tune,offtime_data
public :: lobsdiagsave,lobsdiag_forenkf,blacklst,hilbert_curve,lobskeep,time_window_max,sfcmodel,ext_sonde
@@ -470,12 +480,13 @@ module obsmod
! ==== DBZ DA ===
public :: ntilt_radarfiles
public :: whichradar
- public :: vr_dealisingopt, if_vterminal, if_model_dbz, inflate_obserr, if_vrobs_raw, l2rwthin
+ public :: vr_dealisingopt, if_vterminal, if_model_dbz, if_vrobs_raw, if_use_w_vr, l2rwthin
+ public :: inflate_dbz_obserr
public :: doradaroneob,oneoblat,oneoblon
public :: oneobddiff,oneobvalue,oneobheight,oneobradid
- public :: ens_hx_dbz_cut,static_gsi_nopcp_dbz,rmesh_dbz,zmesh_dbz,rmesh_vr,zmesh_vr
- public :: radar_no_thinning
+ public :: ens_hx_dbz_cut,static_gsi_nopcp_dbz,rmesh_dbz,zmesh_dbz,rmesh_vr,zmesh_vr,pmot_dbz
+ public :: radar_no_thinning,pmot_vr
public :: mintiltvr,maxtiltvr,minobrangevr,maxobrangevr
public :: mintiltdbz,maxtiltdbz,minobrangedbz,maxobrangedbz
public :: debugmode
@@ -483,7 +494,14 @@ module obsmod
public :: iout_dbz, mype_dbz
! --- DBZ DA ---
-
+
+ ! ==== FED DA ===
+ public :: if_model_fed, innov_use_model_fed
+ public :: r_hgt_fed
+ public :: iout_fed, mype_fed
+ public :: dofedoneob
+ ! --- FED DA ---
+
public :: obsmod_init_instr_table
public :: obsmod_final_instr_table
public :: nobs_sub
@@ -572,7 +590,7 @@ module obsmod
real(r_kind) perturb_fact,time_window_max,time_offset,time_window_rad
real(r_kind),dimension(50):: dmesh
-
+ real(r_kind) r_hgt_fed
integer(i_kind) nchan_total,ianldate
integer(i_kind) ndat,ndat_types,ndat_times,nprof_gps
integer(i_kind) lunobs_obs,nloz_v6,nloz_v8,nobskeep,nloz_omi
@@ -583,12 +601,12 @@ module obsmod
integer(i_kind) iout_co,iout_gust,iout_vis,iout_pblh,iout_tcamt,iout_lcbas
integer(i_kind) iout_cldch
integer(i_kind) iout_wspd10m,iout_td2m,iout_mxtm,iout_mitm,iout_pmsl,iout_howv
- integer(i_kind) iout_uwnd10m,iout_vwnd10m
+ integer(i_kind) iout_uwnd10m,iout_vwnd10m,iout_fed
integer(i_kind) mype_t,mype_q,mype_uv,mype_ps,mype_pw, &
mype_rw,mype_dw,mype_gps,mype_sst, &
mype_tcp,mype_lag,mype_co,mype_gust,mype_vis,mype_pblh, &
mype_wspd10m,mype_td2m,mype_mxtm,mype_mitm,mype_pmsl,mype_howv,&
- mype_uwnd10m,mype_vwnd10m, mype_tcamt,mype_lcbas, mype_dbz
+ mype_uwnd10m,mype_vwnd10m, mype_tcamt,mype_lcbas, mype_dbz, mype_fed
integer(i_kind) mype_cldch
integer(i_kind) iout_swcp, iout_lwcp
integer(i_kind) mype_swcp, mype_lwcp
@@ -613,11 +631,12 @@ module obsmod
real(r_kind) ,allocatable,dimension(:):: dval
real(r_kind) ,allocatable,dimension(:):: time_window
- integer(i_kind) ntilt_radarfiles,tcp_posmatch,tcp_box
+ integer(i_kind) ntilt_radarfiles,tcp_posmatch,tcp_box,pmot_dbz,pmot_vr
logical :: ta2tb
- logical :: doradaroneob
- logical :: vr_dealisingopt, if_vterminal, if_model_dbz, inflate_obserr, if_vrobs_raw, l2rwthin
+ logical :: doradaroneob,dofedoneob
+ logical :: vr_dealisingopt, if_vterminal, if_model_dbz,if_model_fed, innov_use_model_fed, if_vrobs_raw, if_use_w_vr, l2rwthin
+ logical :: inflate_dbz_obserr
character(4) :: whichradar,oneobradid
real(r_kind) :: oneoblat,oneoblon,oneobddiff,oneobvalue,oneobheight
logical :: radar_no_thinning
@@ -638,6 +657,7 @@ module obsmod
logical lobserver,l_do_adjoint, lobsdiag_forenkf
logical,dimension(0:50):: write_diag
logical diag_radardbz
+ logical diag_fed
logical reduce_diag
logical offtime_data
logical hilbert_curve
@@ -747,12 +767,17 @@ subroutine init_obsmod_dflts
if_vterminal=.false.
l2rwthin =.false.
if_vrobs_raw=.false.
- if_model_dbz=.true.
- inflate_obserr=.false.
+ if_use_w_vr=.true.
+ if_model_dbz=.false.
+ if_model_fed=.false.
+ innov_use_model_fed=.false.
+ inflate_dbz_obserr=.false.
whichradar="KKKK"
oneobradid="KKKK"
doradaroneob=.false.
+ r_hgt_fed=6500_r_kind
+ dofedoneob=.false.
oneoblat=-999_r_kind
oneoblon=-999_r_kind
oneobddiff=-999_r_kind
@@ -763,6 +788,14 @@ subroutine init_obsmod_dflts
static_gsi_nopcp_dbz=0.0_r_kind
rmesh_dbz=2
rmesh_vr=2
+! pmot_dbz values of 0,1,2,3 will save different sets of obs output
+! pmot_dbz - all obs - thin obs
+! pmot_dbz - all obs
+! pmot_dbz - use obs
+! pmot_dbz - use obs + thin obs
+
+ pmot_dbz=0
+ pmot_vr=2
zmesh_dbz=500.0_r_kind
zmesh_vr=500.0_r_kind
minobrangedbz=10000.0_r_kind
@@ -788,6 +821,7 @@ subroutine init_obsmod_dflts
end do
write_diag(1)=.true.
diag_radardbz = .false.
+ diag_fed = .false.
reduce_diag = .false.
use_limit = -1
lobsdiagsave=.false.
@@ -831,7 +865,7 @@ subroutine init_obsmod_dflts
iout_tcp=214 ! synthetic tc-mslp
iout_lag=215 ! lagrangian tracers
iout_co=216 ! co tracers
- iout_aero=217 ! aerosol product (aod)
+ iout_aero=217 ! aerosol product (aod) CURRENTLY NOT USED
iout_gust=218 ! wind gust
iout_vis=219 ! visibility
iout_pblh=221 ! pbl height
@@ -852,6 +886,7 @@ subroutine init_obsmod_dflts
iout_lwcp=236 ! liquid-water content path
iout_light=237 ! lightning
iout_dbz=238 ! radar reflectivity
+ iout_fed=239 ! flash extent density
mype_ps = npe-1 ! surface pressure
mype_t = max(0,npe-2) ! temperature
@@ -886,6 +921,7 @@ subroutine init_obsmod_dflts
mype_lwcp=max(0,npe-31) ! liquid-water content path
mype_light=max(0,npe-32)! GOES/GLM lightning
mype_dbz=max(0,npe-33) ! radar reflectivity
+ mype_fed= max(0,npe-34) ! flash extent density
! Initialize arrays used in namelist obs_input
@@ -980,7 +1016,7 @@ subroutine init_obsmod_dflts
return
end subroutine init_obsmod_dflts
- subroutine init_directories(mype)
+ subroutine init_directories(in_pe,num_pe)
!$$$ subprogram documentation block
! . . . .
! subprogram: create sub-directories
@@ -1005,20 +1041,47 @@ subroutine init_directories(mype)
! machine: ibm rs/6000 sp
!
!$$$ end documentation block
+#ifdef __INTEL_COMPILER
+ use IFPORT
+#endif
implicit none
- integer(i_kind),intent(in ) :: mype
+ integer(i_kind),intent(in ) :: in_pe
+ integer(i_kind),intent(in ) :: num_pe
+ logical :: l_mkdir_stat, l_dir_exist
character(len=144):: command
- character(len=8):: pe_name
+ character(len=8):: pe_name, loc_pe_name
+ character(len=128):: loc_dirname
+ integer(i_kind) :: i, ierror
if (lrun_subdirs) then
- write(pe_name,'(i4.4)') mype
+ write(pe_name,'(i4.4)') in_pe
dirname = 'dir.'//trim(pe_name)//'/'
- command = 'mkdir -p -m 755 ' // trim(dirname)
- call system(command)
+! Only create directories on one PE
+ if(in_pe == 0) then
+ do i = 0, num_pe
+ write(loc_pe_name,'(i4.4)') i
+ loc_dirname = 'dir.'//trim(loc_pe_name)
+#ifdef __INTEL_COMPILER
+ INQUIRE(directory=trim(loc_dirname), exist=l_dir_exist)
+ if (.not.l_dir_exist) then
+ l_mkdir_stat = MAKEDIRQQ(trim(loc_dirname))
+ if(.not.l_mkdir_stat) then
+ ierror=GETLASTERRORQQ()
+ write(6, *) "INIT_DIRECTORIES: ***ERROR** Failed to create directory ", &
+ trim(loc_dirname)," for PE ", loc_pe_name, ' ierror= ', ierror
+ call stop2(678)
+ endif
+ endif
+#else
+ command = 'mkdir -p -m 755 ' // trim(loc_dirname)
+ call system(command)
+#endif
+ enddo
+ endif
else
- write(pe_name,100) mype
+ write(pe_name,100) in_pe
100 format('pe',i4.4,'.')
dirname= trim(pe_name)
end if
diff --git a/src/gsi/pcgsoi.f90 b/src/gsi/pcgsoi.f90
index a4ae2431b1..0b808c5c55 100644
--- a/src/gsi/pcgsoi.f90
+++ b/src/gsi/pcgsoi.f90
@@ -130,8 +130,8 @@ subroutine pcgsoi()
iguess,read_guess_solution, &
niter_no_qc,print_diag_pcg
use gsi_4dvar, only: nobs_bins, nsubwin, l4dvar, iwrtinc, ladtest, &
- iorthomax
- use gridmod, only: twodvar_regional,periodic
+ iorthomax,lsqrtb
+ use gridmod, only: twodvar_regional,periodic,minmype
use constants, only: zero,one,tiny_r_kind
use mpimod, only: mype
use mpl_allreducemod, only: mpl_allreduce
@@ -148,15 +148,17 @@ subroutine pcgsoi()
use bias_predictors, only: update_bias_preds
use xhat_vordivmod, only : xhat_vordiv_init, xhat_vordiv_calc, xhat_vordiv_clean
use timermod, only: timer_ini,timer_fnl
- use hybrid_ensemble_parameters,only : l_hyb_ens,ntlevs_ens
+ use hybrid_ensemble_parameters,only : l_hyb_ens,ntlevs_ens,aniso_a_en
use gsi_bundlemod, only : gsi_bundle
use gsi_bundlemod, only : self_add,assignment(=)
use gsi_bundlemod, only : gsi_bundleprint
+ use gsi_bundlemod, only : gsi_bundlegetpointer
use gsi_4dcouplermod, only : gsi_4dcoupler_grtests
use rapidrefresh_cldsurf_mod, only: i_gsdcldanal_type
use gsi_io, only: verbose
use berror, only: vprecond
use stpjomod, only: stpjo_setup
+ use intradmod, only: setrad
implicit none
@@ -187,7 +189,7 @@ subroutine pcgsoi()
type(control_vector), allocatable, dimension(:) :: cglwork
type(control_vector), allocatable, dimension(:) :: cglworkhat
integer(i_kind) :: iortho
- logical :: print_verbose
+ logical :: print_verbose,ortho,diag_print
logical :: lanlerr,read_success
! Step size diagnostic strings
@@ -235,7 +237,9 @@ subroutine pcgsoi()
nlnqc_iter=.false.
call stpjo_setup(nobs_bins)
+ ortho=.false.
if(iorthomax>0) then
+ ortho=.true.
allocate(cglwork(iorthomax+1))
DO ii=1,iorthomax+1
CALL allocate_cv(cglwork(ii))
@@ -252,10 +256,19 @@ subroutine pcgsoi()
end do
sbias=zero
+ call setrad(sval(1))
+ if(l_hyb_ens .and. .not. aniso_a_en) then
+ if (lsqrtb) then
+ write(6,*)'l_hyb_ens: not for use with lsqrtb'
+ call stop2(317)
+ end if
+ end if
! Perform inner iteration
inner_iteration: do iter=0,niter(jiter)
+
+ diag_print= iter <= 1 .and. print_diag_pcg
-! Gradually turn on variational qc to avoid possible convergence problems
+! Gradually turn on old variational qc to avoid possible convergence problems
if(vqc) then
nlnqc_iter = iter >= niter_no_qc(jiter)
if(jiter == jiterstart) then
@@ -266,17 +279,11 @@ subroutine pcgsoi()
endif
end if
! 1. Calculate gradient
- do ii=1,nobs_bins
- rval(ii)=zero
- end do
- rbias=zero
gradx=zero
- llprt=(mype==0).and.(iter<=1)
-! Control to state
-! call c2s(xhat,sval,sbias,llprt,.true.)
+ llprt=(mype==minmype).and.(iter<=1)
- if (iter<=1 .and. print_diag_pcg) then
+ if (diag_print) then
do ii=1,nobs_bins
call prt_state_norms(sval(ii),'sval')
enddo
@@ -285,20 +292,23 @@ subroutine pcgsoi()
! Compare obs to solution and transpose back to grid
call intall(sval,sbias,rval,rbias)
- if (iter<=1 .and. print_diag_pcg) then
+ if (diag_print) then
do ii=1,nobs_bins
call prt_state_norms(rval(ii),'rval')
enddo
endif
+
! Adjoint of control to state
call c2s_ad(gradx,rval,rbias,llprt)
! Print initial Jo table
- if (iter==0 .and. print_diag_pcg .and. luse_obsdiag) then
- nprt=2
- call evaljo(zjo,iobs,nprt,llouter)
- call prt_control_norms(gradx,'gradx')
+ if (iter==0) then
+ if(print_diag_pcg .and. luse_obsdiag) then
+ nprt=2
+ call evaljo(zjo,iobs,nprt,llouter)
+ call prt_control_norms(gradx,'gradx')
+ end if
endif
! Add contribution from background term
@@ -308,7 +318,7 @@ subroutine pcgsoi()
! End of gradient calculation
! Re-orthonormalization if requested
- if(iorthomax>0) then
+ if(ortho) then
iortho=min(iorthomax,iter)
if(iter .ne. 0) then
do ii=iortho,1,-1
@@ -323,13 +333,13 @@ subroutine pcgsoi()
! 2. Multiply by background error
call multb(gradx,grady)
- if(iorthomax>0) then
+ if(ortho) then
! save gradients
if (iter <= iortho) then
- zdla = sqrt(dot_product(gradx,grady,r_quad))
+ zdla = one/sqrt(dot_product(gradx,grady,r_quad))
do i=1,nclen
- cglwork(iter+1)%values(i)=gradx%values(i)/zdla
- cglworkhat(iter+1)%values(i)=grady%values(i)/zdla
+ cglwork(iter+1)%values(i)=gradx%values(i)*zdla
+ cglworkhat(iter+1)%values(i)=grady%values(i)*zdla
end do
end if
end if
@@ -350,7 +360,7 @@ subroutine pcgsoi()
! different due to round off, so use average.
gnorm(2)=dprod(2)-0.5_r_quad*(dprod(3)+dprod(4))
gnorm(3)=dprod(2)
- if(mype == 0)then
+ if(mype == minmype)then
aindex=abs(dprod(3)/dprod(2))
write(iout_iter,*) 'NL Index ',aindex
if(aindex > 0.5_r_kind .or. print_verbose) write(iout_iter,*) 'NL Values ', dprod(3),dprod(2)
@@ -370,7 +380,7 @@ subroutine pcgsoi()
gnorm(1)=dprod(1)
- if(mype == 0)write(iout_iter,*)'Minimization iteration',iter
+ if(mype == minmype)write(iout_iter,*)'Minimization iteration',iter
! 4. Calculate b and new search direction
b=zero
@@ -378,13 +388,13 @@ subroutine pcgsoi()
if (iter > 1 .or. .not. read_success)then
if (gsave>1.e-16_r_kind) b=gnorm(2)/gsave
if (b30.0_r_kind) then
- if (mype==0) then
+ if (mype==minmype) then
if (iout_6) write(6,105) gnorm(2),gsave,b
write(iout_iter,105) gnorm(2),gsave,b
endif
b=zero
endif
- if (mype==0 .and. print_verbose) write(6,888)'pcgsoi: gnorm(1:3),b=',gnorm,b
+ if (mype==minmype .and. print_verbose) write(6,888)'pcgsoi: gnorm(1:3),b=',gnorm,b
end if
do i=1,nclen
@@ -432,22 +442,20 @@ subroutine pcgsoi()
gnormx=gnorm(1)/gnormorig
penx=penalty/penorig
- if (mype==0) then
+ if (mype==minmype) then
if (iter==0) then
zgini=gnorm(1)
zfini=penalty
write(6,888)'Initial cost function =',zfini
write(6,888)'Initial gradient norm =',sqrt(zgini)
endif
- if(print_verbose)then
- write(iout_iter,888)'pcgsoi: gnorm(1:2)',gnorm
- write(iout_iter,999)'costterms Jb,Jo,Jc,Jl =',jiter,iter,fjcost
- end if
istep=1
if (stptiny_r_kind .and. zfini>tiny_r_kind) then
write(iout_iter,9993) 'estimated penalty reduction this iteration',&
jiter,iter,(penalty-penaltynew),(penalty-penaltynew)/penorig,'%'
@@ -467,7 +475,7 @@ subroutine pcgsoi()
if(gnormx < converge .or. penalty < converge .or. &
penx >= pennorm .or. end_iter)then
- if(mype == 0)then
+ if(mype == minmype)then
if(iout_6) write(6,101)
write(iout_iter,101)
@@ -508,7 +516,7 @@ subroutine pcgsoi()
! End of inner iteration
! Deallocate space for renormalization
- if(iorthomax>0) then
+ if(ortho) then
do ii=1,iorthomax+1
call deallocate_cv(cglwork(ii))
enddo
@@ -521,7 +529,7 @@ subroutine pcgsoi()
! Calculate adjusted observation error factor
if( oberror_tune .and. (.not.l4dvar) ) then
- if (mype == 0) write(6,*) 'PCGSOI: call penal for obs perturbation'
+ if (mype == minmype) write(6,*) 'PCGSOI: call penal for obs perturbation'
! call c2s(xhat,sval,sbias,.false.,.false.)
call penal(sval(1))
@@ -535,17 +543,14 @@ subroutine pcgsoi()
if (l_tlnmc .and. baldiag_inc) call strong_baldiag_inc(sval,size(sval))
- llprt=(mype==0)
+ llprt=(mype==minmype)
! call c2s(xhat,sval,sbias,llprt,.false.)
if(print_diag_pcg)then
! Evaluate final cost function and gradient
- if (mype==0) write(6,*)'Minimization final diagnostics'
+ if (mype==minmype) write(6,*)'Minimization final diagnostics'
- do ii=1,nobs_bins
- rval(ii)=zero
- end do
call intall(sval,sbias,rval,rbias)
gradx=zero
call c2s_ad(gradx,rval,rbias,llprt)
@@ -575,16 +580,16 @@ subroutine pcgsoi()
! fjcost(1) = dot_product(xhatsave,yhatsave,r_quad)
end if
! fjcost(2) = zjo
- zfend=penaltynew
-! if(l_hyb_ens) zfend=zfend+fjcost_e
- if (mype==0) then
+ if (mype==minmype) then
+ zfend=penaltynew
if(l_hyb_ens) then
! If hybrid ensemble run, print out contribution to Jb and Je separately
write(iout_iter,999)'costterms Jb,Je,Jo,Jc,Jl =',jiter,iter,fjcostnew(1)- fjcost_e, &
fjcost_e,fjcostnew(2:4)
+! zfend=zfend+fjcost_e
else
write(iout_iter,999)'costterms Jb,Jo,Jc,Jl =',jiter,iter,fjcostnew
@@ -633,13 +638,7 @@ subroutine pcgsoi()
! Write output analysis files
if(.not.l4dvar) call prt_guess('analysis')
call prt_state_norms(sval(1),'increment')
- if (twodvar_regional) then
- call write_all(-1)
- else
- if(jiter == miter) then
- call write_all(-1)
- endif
- endif
+ if (twodvar_regional .or. jiter == miter) call write_all(-1)
! Overwrite guess with increment (4d-var only, for now)
if (iwrtinc>0) then
@@ -905,6 +904,8 @@ subroutine c2s(hat,val,bias,llprt,ltest)
use gsi_bundlemod, only : gsi_bundle,assignment(=)
use gsi_4dvar, only: nobs_bins, nsubwin, l4dvar
use gsi_4dcouplermod, only : gsi_4dcoupler_grtests
+ use control2state_mod, only: control2state,control2state_ad
+ use ensctl2state_mod, only: ensctl2state
implicit none
type(control_vector) ,intent(inout) :: hat
@@ -971,6 +972,8 @@ subroutine c2s_ad(hat,val,bias,llprt)
use gsi_bundlemod, only : gsi_bundle,assignment(=)
use gsi_bundlemod, only : self_add
use gsi_4dvar, only: nobs_bins, nsubwin, l4dvar
+ use control2state_mod, only: control2state_ad
+ use ensctl2state_mod, only: ensctl2state_ad
implicit none
type(control_vector) ,intent(inout) :: hat
diff --git a/src/gsi/polcarf.f90 b/src/gsi/polcarf.f90
index 4ed450daa1..f2038d9d95 100644
--- a/src/gsi/polcarf.f90
+++ b/src/gsi/polcarf.f90
@@ -617,7 +617,7 @@ subroutine polcas(afg,axr,nxem,norm,naxr,wtaxs,wtxrs,inaxs,inxrs,nf,mr,nr)
do i=0,naxr-1
valp=valp+axr(i,mr+1)
end do
- valp=valp/float(naxr)
+ valp=valp/real(naxr,r_kind)
do i=0,naxr-1
axr(i,mr)=valp
end do
@@ -692,7 +692,7 @@ subroutine polcasa(afg,axr,nxem,norm,naxr,wtaxs,wtxrs,inaxs,inxrs,nf,mr,nr)
do i=0,naxr-1
valp=valp+axr(i,mr)
end do
- valp=valp/float(naxr)
+ valp=valp/real(naxr,r_kind)
do i=0,naxr-1
axr(i,mr)=zero
axr(i,mr+1)=axr(i,mr+1)+valp
diff --git a/src/gsi/prewgt.f90 b/src/gsi/prewgt.f90
index 38d61050fe..7f3d2fc091 100644
--- a/src/gsi/prewgt.f90
+++ b/src/gsi/prewgt.f90
@@ -273,7 +273,7 @@ subroutine prewgt(mype)
end do
do j=1,lon2
do i=1,lat2
- temp(i,j)=float(isli2(i,j))
+ temp(i,j)=real(isli2(i,j),r_kind)
end do
end do
@@ -585,7 +585,7 @@ subroutine prewgt(mype)
! rearth_equator is the equatorial radius from a 1999 IAG report. The
! horizontal scales are defined at the equator, hence the need for the
! equatorial radius.
- s2u=(two*pi*rearth_equator)/float(nlon)
+ s2u=(two*pi*rearth_equator)/real(nlon,r_kind)
allocate(sli(ny,nx,2,nnnn1o),sli1(-nf:nf,-nf:nf,2,nnnn1o), &
diff --git a/src/gsi/prewgt_reg.f90 b/src/gsi/prewgt_reg.f90
index bde1c9dece..d79a06697e 100644
--- a/src/gsi/prewgt_reg.f90
+++ b/src/gsi/prewgt_reg.f90
@@ -164,7 +164,6 @@ subroutine prewgt_reg(mype)
real(r_kind),allocatable,dimension(:,:,:,:)::sli
real(r_quad),dimension(180,nsig):: ozmz,cnt
real(r_quad),dimension(180*nsig):: ozmz0,cnt0
- real(r_kind),dimension(180,nsig):: ozmzt,cntt
real(r_kind),dimension(:,:,:),pointer::ges_oz=>NULL()
@@ -267,13 +266,13 @@ subroutine prewgt_reg(mype)
do k=1,nsig
do ix=1,180
i=i+1
- ozmzt(ix,k)=ozmz0(i)
- cntt(ix,k)=cnt0(i)
+ ozmz(ix,k)=ozmz0(i)
+ cnt(ix,k)=cnt0(i)
end do
end do
do k=1,nsig
do i=1,180
- if(cntt(i,k)>zero) ozmzt(i,k)=sqrt(ozmzt(i,k)/cntt(i,k))
+ if(cnt(i,k)>zero) ozmz(i,k)=sqrt(ozmz(i,k)/cnt(i,k))
enddo
enddo
endif ! regional_ozone
@@ -452,10 +451,10 @@ subroutine prewgt_reg(mype)
d=region_lat(il,jl)*rad2deg+90._r_kind
l=int(d)
l2=l+1
- dl2=d-float(l)
+ dl2=d-real(l,r_kind)
dl1=one-dl2
do k=1,nsig
- dssv(i,j,k,n)=(dl1*ozmzt(l,k)+dl2*ozmzt(l2,k))*dsv(1,k,llmin)
+ dssv(i,j,k,n)=(dl1*ozmz(l,k)+dl2*ozmz(l2,k))*dsv(1,k,llmin)
end do
end do
end do
@@ -581,7 +580,7 @@ subroutine prewgt_reg(mype)
do i=1,lon2
l=int(rllat1(j,i))
l2=min0(l+1,llmax)
- dl2=rllat1(j,i)-float(l)
+ dl2=rllat1(j,i)-real(l,r_kind)
dl1=one-dl2
do k=1,nsig
dssv(j,i,k,n)=dl1*dsv(i,k,l)+dl2*dsv(i,k,l2)
@@ -604,7 +603,7 @@ subroutine prewgt_reg(mype)
do i=1,lon2
l=int(rllat1(j,i))
l2=min0(l+1,llmax)
- dl2=rllat1(j,i)-float(l)
+ dl2=rllat1(j,i)-real(l,r_kind)
dl1=one-dl2
do k=1,nsig
dssv(j,i,k,n)=dl1*dsv(i,k,l)+dl2*dsv(i,k,l2)
@@ -662,7 +661,7 @@ subroutine prewgt_reg(mype)
do i=1,lon2
l=int(rllat1(j,i))
l2=min0(l+1,llmax)
- dl2=rllat1(j,i)-float(l)
+ dl2=rllat1(j,i)-real(l,r_kind)
dl1=one-dl2
dssvs(j,i,n)=dl1*dsvs(i,l)+dl2*dsvs(i,l2)
if (mvars>=2.and.n==nrf2_sst) then
@@ -738,7 +737,7 @@ subroutine prewgt_reg(mype)
do j=1,ny
l=int(rllat(j,i))
lp=min0(l+1,llmax)
- dl2=rllat(j,i)-float(l)
+ dl2=rllat(j,i)-real(l,r_kind)
dl1=one-dl2
fact=one/(dl1*hwll(l,k1,nn)+dl2*hwll(lp,k1,nn))
slw((i-1)*ny+j,k)=slw((i-1)*ny+j,1)*fact**2
@@ -778,7 +777,7 @@ subroutine prewgt_reg(mype)
do j=1,ny
l=int(rllat(j,i))
lp=min0(l+1,llmax)
- dl2=rllat(j,i)-float(l)
+ dl2=rllat(j,i)-real(l,r_kind)
dl1=one-dl2
fact=cc/(dl1*hwllp(l,nn)+dl2*hwllp(lp,nn))
slw((i-1)*ny+j,k)=slw((i-1)*ny+j,1)*fact**2
diff --git a/src/gsi/pvqc.f90 b/src/gsi/pvqc.f90
index 81d27ba99f..3353b091a3 100755
--- a/src/gsi/pvqc.f90
+++ b/src/gsi/pvqc.f90
@@ -382,8 +382,8 @@ subroutine vqch_iii(ia,ib,ik,x,g,w)! [vqch]
g=g-ya
w=-w/xx
else
- g=-qx**2/2
- w=1
+ g=-qx**2/2_dp
+ w=1_dp
endif
g=p*g
end subroutine vqch_iii
diff --git a/src/gsi/q_diag.f90 b/src/gsi/q_diag.f90
index 925a5775ec..fe5f2f0e94 100644
--- a/src/gsi/q_diag.f90
+++ b/src/gsi/q_diag.f90
@@ -38,7 +38,7 @@ subroutine q_diag(it,mype)
use mpimod, only: mpi_rtype,mpi_comm_world,mpi_sum,ierror
use constants,only: zero,two,one,half
use gridmod, only: lat2,lon2,nsig,nlat,nlon,lat1,lon1,iglobal,&
- displs_g,ijn,wgtlats,itotsub,strip
+ displs_g,ijn,wgtlats,itotsub,strip,minmype
use derivsmod, only: cwgues
use general_commvars_mod, only: load_grid
use gridmod, only: regional
@@ -67,7 +67,7 @@ subroutine q_diag(it,mype)
real(r_kind),pointer,dimension(:,:,:):: ges_q =>NULL()
real(r_kind),pointer,dimension(:,:,:):: ges_cwmr_it=>NULL()
- mype_out=0
+ mype_out=minmype
mm1=mype+1
ier=0
@@ -147,7 +147,7 @@ subroutine q_diag(it,mype)
call load_grid(work_pw,grid_pw)
globps=zero
globpw=zero
- rlon=one/float(nlon)
+ rlon=one/real(nlon,r_kind)
do jj=2,nlat-1
j=jj-1
fmeanps=zero
diff --git a/src/gsi/qcmod.f90 b/src/gsi/qcmod.f90
index f4afdbae9d..3b685d0708 100644
--- a/src/gsi/qcmod.f90
+++ b/src/gsi/qcmod.f90
@@ -115,6 +115,9 @@ module qcmod
! def vadfile - local name of bufr file containing vad winds (used by read_radar)
! def use_poq7 - if true, accept sbuv/2 obs with profile ozone quality flag 7
! def cao_check - if true, turn on cold-air-outbreak screening
+! def airs_cads - if true, use the cloud and aerosol detection routine for Aqua/AIRS instrument
+! def cris_cads - if true, use the cloud and aerosol detection routine for CrIS instruments
+! def iasi_cads - if true, use the cloud and aerosol detection routine for IASI instruments
!
! following used for nonlinear qc:
!
@@ -147,12 +150,12 @@ module qcmod
!
!$$$ end documentation block
- use kinds, only: i_kind,r_kind,r_double
+ use kinds, only: i_kind,r_kind,r_double, r_single
use constants, only: zero,quarter,half,one,two,three,four,five,tiny_r_kind,rd,grav
use constants, only: r0_01,r0_02,r0_03,r0_04,r0_05,r10,r60,r100,h300,r400,r1000,r2000,r2400,r4000
use constants, only: deg2rad,rad2deg,t0c,one_tenth,rearth_equator
use obsmod, only: rmiss_single
- use radinfo, only: iuse_rad,passive_bc
+ use radinfo, only: iuse_rad,passive_bc,nuchan
use radinfo, only: tzr_qc
use radiance_mod, only: rad_obs_type
implicit none
@@ -183,6 +186,7 @@ module qcmod
public :: qc_gmi
public :: qc_amsr2
public :: qc_saphir
+
! set passed variables to public
public :: npres_print,nlnqc_iter,varqc_iter,pbot,ptop,c_varqc,njqc,vqc,nvqc,hub_norm
public :: use_poq7,noiqc,vadfile,dfact1,dfact,erradar_inflate,gps_jacqc
@@ -193,13 +197,14 @@ module qcmod
public :: ifail_iland_det, ifail_isnow_det, ifail_iice_det, ifail_iwater_det,&
ifail_imix_det, ifail_iomg_det, ifail_isst_det, ifail_itopo_det,&
ifail_iwndspeed_det
- public :: cao_check
+ public :: cao_check, ifail_clrfrac_geocsr_qc !emily
public :: buddycheck_t,buddydiag_save
public :: vadwnd_l2rw_qc
public :: pvis,pcldch,scale_cv,estvisoe,estcldchoe,vis_thres,cldch_thres
public :: troflg
public :: lat_c
public :: nrand
+ public :: airs_cads, cris_cads, iasi_cads
logical nlnqc_iter,njqc,vqc,nvqc,hub_norm
logical noiqc
@@ -215,6 +220,7 @@ module qcmod
logical vadwnd_l2rw_qc
logical troflg
logical cao_check
+ logical airs_cads, cris_cads, iasi_cads
character(10):: vadfile
integer(i_kind) npres_print
@@ -247,6 +253,7 @@ module qcmod
integer(i_kind),parameter:: ifail_surface_qc=5
! Reject due to gross check in specific qc routine
integer(i_kind),parameter:: ifail_gross_routine_qc=6
+ integer(i_kind),parameter:: ifail_gross_routine_nonsea_qc=16
! Reject due to cloud > limit for channel in qc routine
integer(i_kind),parameter:: ifail_cloud_qc=7
! Reject due to inaccurate emissivity/surface temperature estimate in qc routine
@@ -354,8 +361,9 @@ module qcmod
! QC_geocsr
! Reject because of standard deviation in subroutine qc_geocsr
- integer(i_kind),parameter:: ifail_std_geocsr_qc=50
-
+! integer(i_kind),parameter:: ifail_std_geocsr_qc=50
+ integer(i_kind),parameter:: ifail_std_geocsr_qc=52 !emily change from 50 to 52
+ integer(i_kind),parameter:: ifail_clrfrac_geocsr_qc=51 !emily
! QC_avhrr
! Reject because of too large surface temperature physical retrieval in qc routine: tz_retrieval (see tzr_qc)
integer(i_kind),parameter:: ifail_tzr_qc=10
@@ -455,6 +463,10 @@ subroutine init_qcvars
lat_c=21.0_r_kind
nrand=13
+ airs_cads = .false.
+ cris_cads = .false.
+ iasi_cads = .false.
+
return
end subroutine init_qcvars
@@ -1085,6 +1097,15 @@ end subroutine tz_retrieval
subroutine qc_ssmi(nchanl,nsig,ich,sfchgt,luse,sea,mixed, &
temp,wmix,ts,pems,ierrret,kraintype,tpwc,clw,sgagl,tzbgr, &
tbc,tbcnob,tb_ges,tnoise,ssmi,amsre_low,amsre_mid,amsre_hig,ssmis, &
+ varinv_after_grossroutinechk_over_ocean, & !emily
+ varinv_after_topo, & !emily
+ varinv_after_sfcchk, & !emily
+ varinv_after_ch2chk, & !emily
+ varinv_after_grossroutinechk,& !emily
+ varinv_after_scatteringchk, & !emily
+ varinv_after_nsstret, & !emily
+ varinv_after_jsfcchk, & !emily
+ pred9,pred10,pred11, & !emily
varinv,errf,aivals,id_qc)
! varinv,errf,aivals,id_qc,radmod) ! all-sky
@@ -1197,6 +1218,15 @@ subroutine qc_ssmi(nchanl,nsig,ich,sfchgt,luse,sea,mixed, &
real(r_kind),dimension(nsig,nchanl),intent(in ) :: temp,wmix
real(r_kind) ,dimension(nchanl),intent(inout) :: varinv,errf
+ real(r_kind) ,dimension(nchanl),intent( out) :: varinv_after_grossroutinechk_over_ocean !emily
+ real(r_kind) ,dimension(nchanl),intent( out) :: varinv_after_grossroutinechk !emily
+ real(r_kind) ,dimension(nchanl),intent( out) :: varinv_after_topo !emily
+ real(r_kind) ,dimension(nchanl),intent( out) :: varinv_after_sfcchk !emily
+ real(r_kind) ,dimension(nchanl),intent( out) :: varinv_after_ch2chk !emily
+ real(r_kind) ,dimension(nchanl),intent( out) :: varinv_after_scatteringchk !emily
+ real(r_kind) ,dimension(nchanl),intent( out) :: varinv_after_nsstret !emily
+ real(r_kind) ,dimension(nchanl),intent( out) :: varinv_after_jsfcchk !emily
+ real(r_kind) ,intent( out) :: pred9,pred10,pred11 !emily
real(r_kind) ,dimension(40) ,intent(inout) :: aivals
! Declare local variables
@@ -1204,7 +1234,7 @@ subroutine qc_ssmi(nchanl,nsig,ich,sfchgt,luse,sea,mixed, &
integer(i_kind) :: l,i
real(r_kind) :: efact,vfact,dtempf,dtbf,term
real(r_kind),dimension(nchanl) :: demisf_mi,clwcutofx
- real(r_kind) :: pred9,pred10,pred11
+!xxx real(r_kind) :: pred9,pred10,pred11 !emily
real(r_kind) :: dtz,ts_ave,xindx,tzchks
!------------------------------------------------------------------
@@ -1248,6 +1278,15 @@ subroutine qc_ssmi(nchanl,nsig,ich,sfchgt,luse,sea,mixed, &
efact =one
vfact =one
+ do i = 1,24
+ varinv_after_grossroutinechk_over_ocean(i) = varinv(i) !emily
+ varinv_after_topo(i) = varinv(i) !emily
+ varinv_after_sfcchk(i) = varinv(i) !emily
+ varinv_after_ch2chk(i) = varinv(i) !emily
+ varinv_after_grossroutinechk(i) = varinv(i) !emily
+ enddo
+
+
! Over sea
if(sea) then
@@ -1271,6 +1310,7 @@ subroutine qc_ssmi(nchanl,nsig,ich,sfchgt,luse,sea,mixed, &
varinv(i) = zero
id_qc(i) = ifail_gross_routine_qc
end if
+ varinv_after_grossroutinechk_over_ocean(i) = varinv(i) !emily
enddo
else if(amsre_low .and. sgagl < 25.0_r_kind) then
@@ -1347,6 +1387,7 @@ subroutine qc_ssmi(nchanl,nsig,ich,sfchgt,luse,sea,mixed, &
do i=1,24
varinv(i)=zero
if(id_qc(i)== igood_qc) id_qc(i)=ifail_topo_ssmi_qc
+ varinv_after_topo(i) = varinv(i) !emily
enddo
else
!Use dtbc at 52.8 GHz to detect cloud-affected data
@@ -1359,7 +1400,8 @@ subroutine qc_ssmi(nchanl,nsig,ich,sfchgt,luse,sea,mixed, &
varinv(i)=zero
if(id_qc(i)== igood_qc) id_qc(i)=ifail_surface_qc
end do
- else if (abs(tbc(2)) >= 1.5_r_kind) then ! the data at cloud-affected channels are not used
+ varinv_after_sfcchk(:) = varinv(:) !emily
+else if (abs(tbc(2)) >= 1.5_r_kind) then ! the data at cloud-affected channels are not used
do i =1,2
varinv(i) = zero
if(id_qc(i)== igood_qc ) id_qc(i)=ifail_ch2_qc
@@ -1368,12 +1410,14 @@ subroutine qc_ssmi(nchanl,nsig,ich,sfchgt,luse,sea,mixed, &
varinv(i) = zero
if(id_qc(i)== igood_qc ) id_qc(i)=ifail_ch2_qc
end do
+ varinv_after_ch2chk(:) = varinv(:) !emily
endif
!General qc criteria for all channels
do i = 1,24
if( abs(tbcnob(i)) >= 3.5_r_kind) then
varinv(i) = zero
- if(id_qc(i)== igood_qc ) id_qc(i)=ifail_gross_routine_qc
+ ! if(id_qc(i)== igood_qc ) id_qc(i)=ifail_gross_routine_qc
+ if(id_qc(i)== igood_qc ) id_qc(i)=ifail_gross_routine_nonsea_qc !emily
end if
enddo
@@ -1392,6 +1436,13 @@ subroutine qc_ssmi(nchanl,nsig,ich,sfchgt,luse,sea,mixed, &
end if
end if
+!>>emily
+ do i = 1, nchanl
+ varinv_after_scatteringchk(i) = varinv(i) !emily
+ enddo
+!< two) then
varinv(9) =zero
if(id_qc(9)== igood_qc) id_qc(9)=ifail_scatt_qc
+ varinv_after_scatteringchk(9) = varinv(9) !emily
end if
if(pred10 - tbcnob(10) - tb_ges(10) > two) then
varinv(10)=zero
if(id_qc(10)== igood_qc) id_qc(10)=ifail_scatt_qc
+ varinv_after_scatteringchk(10) = varinv(10) !emily
end if
if(pred11 - tbcnob(11) - tb_ges(11) > two) then
varinv(11)=zero
if(id_qc(11)== igood_qc) id_qc(11)=ifail_scatt_qc
+ varinv_after_scatteringchk(11) = varinv(11) !emily
end if
end if
!
@@ -1437,6 +1491,11 @@ subroutine qc_ssmi(nchanl,nsig,ich,sfchgt,luse,sea,mixed, &
endif
endif
+ do l=1,nchanl
+ varinv_after_nsstret(:) = varinv(:) !emily
+ enddo
+
+
! Generate q.c. bounds and modified variances.
do l=1,nchanl
@@ -1452,6 +1511,8 @@ subroutine qc_ssmi(nchanl,nsig,ich,sfchgt,luse,sea,mixed, &
endif
+ varinv_after_jsfcchk(l) = varinv(l) !emily
+
end do ! l (ch) loop end
@@ -2065,10 +2126,11 @@ subroutine qc_saphir(nchanl,sfchgt,luse,sea, &
return
end subroutine qc_saphir
-subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
- cris, hirs, zsges,cenlat,frac_sea,pangs,trop5,zasat,tzbgr,tsavg5,tbc,tb_obs,tbcnob,tnoise, &
- wavenumber,ptau5,prsltmp,tvp,temp,wmix,emissivity_k,ts, &
- id_qc,aivals,errf,varinv,varinv_use,cld,cldp,kmax,zero_irjaco3_pole)
+subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr,airs, &
+ cris,iasi,hirs,zsges,cenlat,frac_sea,pangs,trop5,zasat,tzbgr,tsavg5,tbc,tb_obs,tbcnob,tnoise, &
+ wavenumber,ptau5,prsltmp,tvp,temp,wmix,chan_level,emissivity_k,ts,tsim, &
+ id_qc,aivals,errf,varinv,varinv_use,cld,cldp,kmax,zero_irjaco3_pole,cluster_fraction, &
+ cluster_bt, chan_stdev, model_bt)
! id_qc,aivals,errf,varinv,varinv_use,cld,cldp,kmax,zero_irjaco3_pole,radmod) ! all-sky
!$$$ subprogram documentation block
@@ -2108,6 +2170,7 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
! tzbgr - Tz over water
! tsavg5 - surface skin temperature
! tbc - simulated - observed BT with bias correction
+! tsim - simulated BT
! tb_obs - observed Brightness temperatures
! tnoise - channel noise array
! wavenumber - array of channel wavenumbers
@@ -2133,6 +2196,10 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
! cld - cloud fraction
! cldp - cloud pressure
! zero_irjaco3_pole - logical to control use of ozone jacobians near poles
+! cluster_fraction - size of imager derived cluster to determine clear cloudy profiles, used by CADS
+! cluster_bt - imager brightness temperature of each cluster, used by CADS
+! chan_stdev - standard deviation of cluster mean temperatures, used by CADS
+! model_bt _ brightness temperature derived from the model's clear profile. used by CADS
!
! attributes:
! language: f90
@@ -2142,11 +2209,13 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
use kinds, only: r_kind, i_kind
use radinfo, only: iomg_det, itopo_det, isst_det
+ use crtm_planck_functions, only: crtm_planck_radiance
+ use cads, only: cloud_aerosol_detection
implicit none
! Declare passed variables
- logical, intent(in ) :: sea,land,ice,snow,luse,goessndr, cris, hirs
+ logical, intent(in ) :: sea,land,ice,snow,luse,goessndr,airs,cris,hirs,iasi
logical, intent(inout) :: zero_irjaco3_pole
integer(i_kind), intent(in ) :: nsig,nchanl,ndat,is
integer(i_kind),dimension(nchanl), intent(in ) :: ich
@@ -2157,10 +2226,14 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
real(r_kind), intent( out) :: cld,cldp
real(r_kind),dimension(40,ndat), intent(inout) :: aivals
real(r_kind),dimension(nchanl), intent(in ) :: tbc,emissivity_k,ts,wavenumber,tb_obs,tbcnob
- real(r_kind),dimension(nchanl), intent(in ) :: tnoise
+ real(r_kind),dimension(nchanl), intent(in ) :: chan_level
+ real(r_kind),dimension(nchanl), intent(in ) :: tnoise,tsim
real(r_kind),dimension(nsig,nchanl),intent(in ) :: ptau5,temp,wmix
real(r_kind),dimension(nsig), intent(in ) :: prsltmp,tvp
real(r_kind),dimension(nchanl), intent(inout) :: errf,varinv,varinv_use
+ real(r_kind),dimension(7), intent(in ) :: cluster_fraction
+ real(r_kind),dimension(2,7), intent(in ) :: cluster_bt
+ real(r_kind),dimension(2), intent(in ) :: chan_stdev, model_bt
! Declare local parameters
@@ -2168,21 +2241,29 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
real(r_kind) :: demisf,dtempf,efact,dtbf,term,cenlatx,sfchgtfact
- real(r_kind) :: sum,sum2,sum3,cloudp,tmp,dts,delta
- real(r_kind),dimension(nchanl) :: dtb
- integer(i_kind) :: i,j,k,kk,lcloud,m
+ real(r_kind) :: sum1,sum2,sum3,tmp,dts,delta
+ integer(i_kind) :: i,j,lcloud,m,isurface_chan
integer(i_kind), dimension(nchanl) :: irday
real(r_kind) :: dtz,ts_ave,xindx,tzchks
real(r_kind),parameter:: tbmax = 550._r_kind
real(r_kind),parameter:: tbmin = 50._r_kind
+! for cloud_aerosol_detect
+ integer(i_kind) :: I_Sensor_ID
+ integer(i_kind),dimension(nchanl) :: chan_array, i_flag_cloud
+ integer(i_kind),dimension(2) :: imager_chans
+ integer(i_kind) :: boundary_layer_pres, tropopause_height
+ integer(i_kind) :: ichan_10_micron, ichan_12_micron
+ real(r_kind),dimension(nchanl) :: tb_bc
+ real(r_kind) :: cloud_temperature, radiance_chan, radiance_model, radiance_cloud
+ real(r_kind) :: tb_obs_10, tb_obs_12, tb_obs_diff
! Reduce weight given to obs for shortwave ir if
! solar zenith angle tiny_r_kind
irday = 1
if (pangs <= 89.0_r_kind .and. frac_sea > zero) then
! QC2 in statsrad
- if(luse)aivals(9,is) = aivals(9,is) + one
+ if(luse) aivals(9,is) = aivals(9,is) + one
do i=1,nchanl
if(wavenumber(i) > r2000)then
if(wavenumber(i) > r2400)then
@@ -2195,7 +2276,7 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
*max(zero,cos(pangs*deg2rad))*oneover400
varinv(i)=tmp*varinv(i)
varinv_use(i)=tmp*varinv_use(i)
- if(id_qc(i) == igood_qc)id_qc(i)=ifail_2000_qc
+!emily if(id_qc(i) == igood_qc)id_qc(i)=ifail_2000_qc
end if
end if
end do
@@ -2225,7 +2306,7 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
! If GOES and lza > 60. do not use
if( goessndr .and. zasat*rad2deg > r60) then
! QC5 in statsrad
- if(luse)aivals(12,is) = aivals(12,is) + one
+ if(luse) aivals(12,is) = aivals(12,is) + one
do i=1,nchanl
varinv(i) = zero
varinv_use(i)=zero
@@ -2237,7 +2318,7 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
sfchgtfact=one
if (zsges > r2000) then
! QC1 in statsrad
- if(luse)aivals(8,is) = aivals(8,is) + one
+ if(luse) aivals(8,is) = aivals(8,is) + one
sfchgtfact = (r2000/zsges)**4
endif
@@ -2265,119 +2346,196 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
cld=zero
cldp=r10*prsltmp(1)
- do k=1,nsig
- if(prsltmp(k) > trop5)then
- do i=1,nchanl
- dtb(i)=(tvp(k)-tsavg5)*ts(i)
- end do
- do kk=1,k-1
- do i=1,nchanl
- dtb(i)=dtb(i)+(tvp(k)-tvp(kk))*temp(kk,i)
- end do
- end do
- sum=zero
- sum2=zero
- do i=1,nchanl
- if(varinv_use(i) > tiny_r_kind)then
- sum=sum+tbc(i)*dtb(i)*varinv_use(i)
- sum2=sum2+dtb(i)*dtb(i)*varinv_use(i)
- end if
- end do
- if (abs(sum2) < tiny_r_kind) sum2 = sign(tiny_r_kind,sum2)
- cloudp=min(max(sum/sum2,zero),one)
- sum=zero
- do i=1,nchanl
- if(varinv_use(i) > tiny_r_kind)then
- tmp=tbc(i)-cloudp*dtb(i)
- sum=sum+tmp*tmp*varinv_use(i)
- end if
- end do
- if(sum < sum3)then
- sum3=sum
- lcloud=k
- cld=cloudp
- cldp=r10*prsltmp(k)
- end if
- end if
+! Cloud and aerosol detection routines (ECMWF)
+ if (cris .and. cris_cads) then
+ I_Sensor_ID = 27
+ chan_array = nuchan(ich) ! channel numbers
+ tb_bc = tbc + tsim ! observation BT with bias correction
+ boundary_layer_pres = nint(0.8_r_kind*prsltmp(1)) ! boundary layer set to be 80% of surface pressure
+ tropopause_height = nint(trop5)
+ imager_chans = (/15,16/) ! imager channel numbers (from satinfo)
+ isurface_chan = 501 ! surface channel
+ ichan_10_micron = 458 ! ~10.7 micron channel for low level cloud test
+ ichan_12_micron = 295 ! ~12.0 micron channel for low level cloud test
+
+ call cloud_aerosol_detection( I_Sensor_ID, nchanl, chan_array, &
+ tropopause_height, boundary_layer_pres, tb_bc, tsim, chan_level, imager_chans, cluster_fraction, &
+ cluster_bt, chan_stdev, model_bt, i_flag_cloud, cldp )
+
+ elseif ( iasi .and. iasi_cads ) then
+ I_Sensor_ID = 16
+ chan_array = nuchan(ich) ! channel numbers
+ tb_bc = tbc + tsim ! observation BT with bias correction
+ boundary_layer_pres = nint(0.8_r_kind*prsltmp(1)) ! boundary layer set to be 80% of surface pressure
+ tropopause_height = nint(trop5)
+ imager_chans = (/2,3/) ! imager channel numbers (from satinfo)
+ isurface_chan = 1271 ! surface channel
+ ichan_10_micron = 1173 ! ~10.7 micron channel for low level cloud test
+ ichan_12_micron = 756 ! ~12.0 micron channel for low level cloud test
+
+ call cloud_aerosol_detection( I_Sensor_ID, nchanl, chan_array, &
+ tropopause_height, boundary_layer_pres, tb_bc, tsim, chan_level, imager_chans, cluster_fraction, &
+ cluster_bt, chan_stdev, model_bt, i_flag_cloud, cldp )
+
+ elseif ( airs .and. airs_cads ) then
+ I_Sensor_ID = 11
+ chan_array = nuchan(ich) ! channel numbers
+ tb_bc = tbc + tsim ! observation BT with bias correction
+ boundary_layer_pres = nint(0.8_r_kind*prsltmp(1)) ! boundary layer set to be 80% of surface pressure
+ tropopause_height = nint(trop5)
+ isurface_chan = 914 ! surface channel
+ imager_chans = (/0,0/) ! imager channel numbers (from satinfo)
+ ichan_10_micron = 843 ! ~10.7 micron channel for low level cloud test
+ ichan_12_micron = 587 ! ~12.0 micron channel for low level cloud test
+
+ call cloud_aerosol_detection( I_Sensor_ID, nchanl, chan_array, &
+ tropopause_height, boundary_layer_pres, tb_bc, tsim, chan_level, imager_chans, cluster_fraction, &
+ cluster_bt, chan_stdev, model_bt, i_flag_cloud, cldp )
- end do
- if ( lcloud > 0 ) then ! If cloud detected, reject channels affected by it.
+ else
+ call emc_legacy_cloud_detect(nchanl,nsig,tsavg5,trop5,prsltmp,tvp,ts,tbc,temp,varinv_use,lcloud,cld,cldp)
- do i=1,nchanl
+ endif ! end of which cloud test to use
+
+! compute cloud stats
+! If using CADS
+ if ((cris .and. cris_cads) .or. (iasi .and. iasi_cads) .or. (airs .and. airs_cads)) then
+
+! Reject channels affected by clouds
+ do i=1, nchanl
+ if ( i_flag_cloud(i) == 1) then
+! QC4 in statsrad
+ if(luse) aivals(11,is) = aivals(11,is) + one
+ varinv(i) = zero
+ varinv_use(i) = zero
+ if(id_qc(i) == igood_qc) id_qc(i) = ifail_cloud_qc
+ endif
+ end do
+
+! Derive cloud amount for CADS
+ cld = zero
+ if ( cldp < prsltmp(1) ) then ! if cloud in this profile exists
+ cloud_layer: do i=2, nsig ! determine which layer the cloud exists.
+ if (prsltmp(i) < cldp) then
+ lcloud = i
+ do j=1, nchanl ! use surface channel to derive cloud amount
+ m = nuchan(ich(j))
+ if ( m == isurface_chan ) then ! interpolate cloud top temperature
+ cloud_temperature = ((tvp(lcloud) -tvp(lcloud -1)/ log(prsltmp(lcloud) / prsltmp(lcloud - 1))) &
+ * log(cldp/prsltmp(lcloud-1))) + tvp(lcloud-1)
+ call crtm_planck_radiance(1,m,tb_bc(j),radiance_chan) ! observation radiance. same as tb_obs + bias correction
+ call crtm_planck_radiance(1,m,tsim(j),radiance_model) ! model derived radiance
+ call crtm_planck_radiance(1,m,cloud_temperature,radiance_cloud) ! cloud top temperature radiance
+ cld = (radiance_chan - radiance_model) / (radiance_cloud - radiance_model)
+ cld = min(max(cld,zero),one)
+ cldp = cldp * r10
+ exit cloud_layer ! cloud layer foound and cloud amount computed
+ endif ! surface channel found
+ end do !surface_chan
+ endif ! cloud found (prsltmp(i) < cldp)
+ end do cloud_layer
+
+! If clear, do a 10.7 - 12 micron test for low level clouds
+ else ! lcloud = 0
+ do i=1, nchanl
+ if ( nuchan(ich(i)) == ichan_10_micron ) tb_obs_10 = tb_obs(i)
+ if ( nuchan(ich(i)) == ichan_12_micron ) tb_obs_12 = tb_obs(i)
+ end do
+ if ( tb_obs_10 > zero .and. tb_obs_12 > zero ) then
+ tb_obs_diff = tb_obs_10 - tb_obs_12
+ if ( tb_obs_diff > 2.20_r_kind ) then ! Assume a cloud exists
+ cldp = prsltmp(1) * r10 ! Assume near surface cloud
+ cld = one ! Assume overcast cloud
+ lcloud = 1
+ endif
+ endif
+ endif
+! If more than 2% of the transmittance comes from the cloud layer, reject the channel (0.02 is a tunable parameter).
+! or CADS flagged a channel to have cloud.
+ if ( lcloud > 0 ) then
+ do i=1, nchanl
+ if ( ptau5(lcloud,i) > 0.02_r_kind ) then
+ if(luse) aivals(11,is) = aivals(11,is) + one ! QC4 in statsrad
+ varinv(i) = zero
+ varinv_use(i) = zero
+ if(id_qc(i) == igood_qc) id_qc(i) = ifail_cloud_qc
+ end if
+ end do
+ endif
+
+! default compute cloud stats, emc_legacy_cloud_detect
+ else
+ if ( lcloud > 0 ) then
+
+ do i=1,nchanl
! reject channels with iuse_rad(j)=-1 when they are peaking below the cloud
j=ich(i)
if (passive_bc .and. iuse_rad(j)==-1) then
- if (lcloud .ge. kmax(i)) then
- if(luse)aivals(11,is) = aivals(11,is) + one
- varinv(i) = zero
- varinv_use(i) = zero
- if(id_qc(i) == igood_qc)id_qc(i)=ifail_cloud_qc
- cycle
- end if
+ if (lcloud .ge. kmax(i)) then
+ if(luse)aivals(11,is) = aivals(11,is) + one
+ varinv(i) = zero
+ varinv_use(i) = zero
+ if(id_qc(i) == igood_qc)id_qc(i)=ifail_cloud_qc
+ cycle
+ end if
end if
! If more than 2% of the transmittance comes from the cloud layer,
! reject the channel (0.02 is a tunable parameter)
- delta = 0.02_r_kind
if ( ptau5(lcloud,i) > 0.02_r_kind) then
-! QC4 in statsrad
- if(luse)aivals(11,is) = aivals(11,is) + one
- varinv(i) = zero
- varinv_use(i) = zero
- if(id_qc(i) == igood_qc)id_qc(i)=ifail_cloud_qc
+! QC4 in statsrad
+ if(luse) aivals(11,is) = aivals(11,is) + one
+ varinv(i) = zero
+ varinv_use(i) = zero
+ if(id_qc(i) == igood_qc) id_qc(i) = ifail_cloud_qc
end if
- end do
+ end do
-! If no clouds check surface temperature/emissivity
-
- else ! If no cloud was detected, do surface temp/emiss checks
- sum=zero
- sum2=zero
- do i=1,nchanl
+ else ! surface consistency and sensitivity chacks. ( if lcoud = 0 )
+ sum1=zero
+ sum2=zero
+ do i=1,nchanl
if ( varinv_use(i) > tiny_r_kind .and. ts(i) > 0.0001_r_kind) then
- sum=sum+tbc(i)*ts(i)*varinv_use(i)
- sum2=sum2+ts(i)*ts(i)*varinv_use(i)
+ sum1 = sum1 +tbc(i)*ts(i)*varinv_use(i)
+ sum2 = sum2+ts(i)*ts(i)*varinv_use(i)
endif
- end do
- if (abs(sum2) < tiny_r_kind) sum2 = sign(tiny_r_kind,sum2)
- dts=abs(sum/sum2)
- if(abs(dts) > one)then
+ end do
+ if (abs(sum2) < tiny_r_kind) sum2 = sign(tiny_r_kind,sum2)
+ dts=abs(sum1/sum2)
+ if(abs(dts) > one)then
if(.not. sea)then
- dts=min(dtempf,dts)
+ dts=min(dtempf,dts)
else
- dts=min(three,dts)
+ dts=min(three,dts)
end if
do i=1,nchanl
- delta=max(r0_05*tnoise(i),r0_02)
- if(abs(dts*ts(i)) > delta)then
-! QC3 in statsrad
- if(luse .and. varinv(i) > zero) &
- aivals(10,is) = aivals(10,is) + one
- varinv(i) = zero
- if(id_qc(i) == igood_qc)id_qc(i)=ifail_sfcir_qc
- end if
- end do
- end if
- endif
+ delta=max(r0_05*tnoise(i),r0_02)
+ if(abs(dts*ts(i)) > delta)then
+! QC3 in statsrad
+ if(luse .and. varinv(i) > zero) aivals(10,is) = aivals(10,is) + one
+ varinv(i) = zero
+ if(id_qc(i) == igood_qc)id_qc(i)=ifail_sfcir_qc
+ endif
+ enddo
+ endif
+ endif
-!
! Temporary additional check for CrIS to reduce influence of land points on window channels (particularly important for bias correction)
-!
- if (cris .and. .not. sea) then
- do i=1,nchanl
- if (ts(i) > 0.2_r_kind) then
+ if (cris .and. .not. sea) then
+ do i=1,nchanl
+ if (ts(i) > 0.2_r_kind) then
! QC3 in statsrad
- if(luse .and. varinv(i) > zero) &
- aivals(10,is) = aivals(10,is) + one
- varinv(i) = zero
- if(id_qc(i) == igood_qc)id_qc(i)=ifail_sfcir_qc
- end if
- end do
- end if
-
+ if(luse .and. varinv(i) > zero) &
+ aivals(10,is) = aivals(10,is) + one
+ varinv(i) = zero
+ if(id_qc(i) == igood_qc) id_qc(i) = ifail_sfcir_qc
+ end if
+ end do
+ end if
+ endif ! derive cloud stats
!
! Apply Tz retrieval
!
@@ -2407,7 +2565,7 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
cenlatx=abs(cenlat)*r0_04
if (cenlatx < one) then
- if(luse)aivals(6,is) = aivals(6,is) + one
+ if(luse) aivals(6,is) = aivals(6,is) + one
efact = half*(cenlatx+one)
do i=1,nchanl
if(varinv(i) > tiny_r_kind) errf(i)=efact*errf(i)
@@ -2419,7 +2577,7 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
if(varinv(i) > tiny_r_kind)then
dtbf = demisf*abs(emissivity_k(i))+dtempf*abs(ts(i))
term = dtbf*dtbf
- if(term > tiny_r_kind)varinv(i)=varinv(i)/(one+varinv(i)*term)
+ if(term > tiny_r_kind) varinv(i) = varinv(i)/(one+varinv(i)*term)
end if
end do
@@ -2435,90 +2593,186 @@ subroutine qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse,goessndr, &
if(hirs) then
do i=1,nchanl
m=ich(i)
- if (iomg_det(m) > 0 .and. i < 4 .and. abs(tbcnob(8)) > 40.0_r_kind) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
- if(iomg_det(m) > 0 .and. i == 12 .and. abs(tbcnob(8)) > 10.0_r_kind) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
-!90S-60S
- if(cenlat >= -90.0_r_kind .and. cenlat < -60.0_r_kind) then
- if(iomg_det(m) > 0 .and. i == 4 .and. abs(tbcnob(8)) > 12.0_r_kind) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
- if(iomg_det(m) > 0 .and. i == 5 .and. abs(tbcnob(8)) > 6.0_r_kind) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
- if(iomg_det(m) > 0 .and. i == 6 .and. abs(tbcnob(8)) > 4.0_r_kind) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
-!60S-30S
- else if(cenlat >= -60.0_r_kind .and. cenlat < -30.0_r_kind) then
- if(iomg_det(m) > 0 .and. i == 4 .and. abs(tbcnob(8)) > 10.0_r_kind) then
+ if(iomg_det(m) > 0 .and. i >= 4 .and. i <= 12)then
+ if (i < 4 .and. abs(tbcnob(8)) > 40.0_r_kind) then
varinv(i) = zero
if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
- if(iomg_det(m) > 0 .and. i == 5 .and. abs(tbcnob(8)) > 2.0_r_kind) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
- if(iomg_det(m) > 0 .and. i == 6 .and. abs(tbcnob(8)) > 1.5_r_kind) then
+ else if(i == 12 .and. abs(tbcnob(8)) > 10.0_r_kind) then
varinv(i) = zero
if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
endif
+!90S-60S
+ if(cenlat >= -90.0_r_kind .and. cenlat < -60.0_r_kind) then
+ if(i == 4 .and. abs(tbcnob(8)) > 12.0_r_kind) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ else if(i == 5 .and. abs(tbcnob(8)) > 6.0_r_kind) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ else if(i == 6 .and. abs(tbcnob(8)) > 4.0_r_kind) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ endif
+!60S-30S
+ else if(cenlat >= -60.0_r_kind .and. cenlat < -30.0_r_kind) then
+ if(i == 4 .and. abs(tbcnob(8)) > 10.0_r_kind) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ else if( i == 5 .and. abs(tbcnob(8)) > 2.0_r_kind) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ else if(i == 6 .and. abs(tbcnob(8)) > 1.5_r_kind) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ endif
!30S-30N
- else if(cenlat >= -30.0_r_kind .and. cenlat < 30.0_r_kind) then
- if(iomg_det(m) > 0 .and. i == 4 .and. abs(tbcnob(8)) > 5.0_r_kind) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
- if(iomg_det(m) > 0 .and. i == 5 .and. (tbcnob(8) < -2.0_r_kind .or. tbcnob(8) > 3.0_r_kind)) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
- if(iomg_det(m) > 0 .and. i == 6 .and. (tbcnob(8) < -1.5_r_kind .or. tbcnob(8) > 3.0_r_kind)) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
+ else if(cenlat >= -30.0_r_kind .and. cenlat < 30.0_r_kind ) then
+ if(i == 4 .and. abs(tbcnob(8)) > 5.0_r_kind) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ else if(i == 5 .and. (tbcnob(8) < -2.0_r_kind .or. tbcnob(8) > 3.0_r_kind)) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ else if(i == 6 .and. (tbcnob(8) < -1.5_r_kind .or. tbcnob(8) > 3.0_r_kind)) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ endif
!30N-60N
- else if(cenlat >= 30.0_r_kind .and. cenlat < 60.0_r_kind) then
- if(iomg_det(m) > 0 .and. i == 4 .and. abs(tbcnob(8)) > 8.0_r_kind) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
- if(iomg_det(m) > 0 .and. i == 5 .and. abs(tbcnob(8)) > 2.0_r_kind) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
- if(iomg_det(m) > 0 .and. i == 6 .and. abs(tbcnob(8)) > 1.0_r_kind) then
- varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
- endif
- endif !cenlat
+ else if(cenlat >= 30.0_r_kind .and. cenlat < 60.0_r_kind) then
+ if(i == 4 .and. abs(tbcnob(8)) > 8.0_r_kind) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ else if(i == 5 .and. abs(tbcnob(8)) > 2.0_r_kind) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ else if(i == 6 .and. abs(tbcnob(8)) > 1.0_r_kind) then
+ varinv(i) = zero
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_iomg_det
+ endif
+ endif !cenlat
+ end if
if (itopo_det(m) > 0 .and. zsges > 1500.0_r_kind) then
varinv(i) = zero
- if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_itopo_det
+ if ( id_qc(i) == igood_qc ) id_qc(i) = ifail_itopo_det
endif
end do
endif !! if (hirs)
!---mkim
+ return
+end subroutine qc_irsnd
+subroutine emc_legacy_cloud_detect(nchanl,nsig,tsavg5,trop5,prsltmp,tvp,ts,tbc,temp,varinv_use,lcloud,cld,cldp)
+
+!$$$ subprogram documentation block
+! . . .
+! subprogram: emc_legacy_cloud_detect determine clear/cloudy profiles from hirs,goessndr,airs,iasi,cris instruments
+!
+! prgmmr: derber ??? org: np23 date: ???
+!
+! abstract: determine if a profile is clear/cloudy. If cloudy, determine model layer of the lcoud.
+! This subroutine is designed for infrared sounders.
+!
+! program history log:
+! 2022-06-20 jung moved into a subroutine
+!
+! input argument list:
+! nchanl - number of channels per obs
+! nsig - number of model layers
+! tsavg5 - surface skin temperature
+! trop5 - tropopause pressure
+! prsltmp - array of layer pressure in vertical (surface to toa)
+! tvp - array of temperatures in vertical (surface to toa)
+! ts - skin temperature sensitivity
+! tbc - simulated - observed BT with bias correction
+! temp - temperature sensitivity array
+! varinv_use - observation weight used (modified obs var error inverse)
+!
+! output argument list:
+! lcloud - model layer of cloud
+! cld - derived cloud amount
+! cldp - model layer pressure (hPa) of cloud
+!
+! attributes:
+! language: f90
+! machine: ibm RS/6000 SP
+!
+!$$$ end documentation block
+
+use kinds, only: i_kind, r_kind
+use constants, only: tiny_r_kind, zero, r10
+implicit none
+
+integer(i_kind), intent(in ) :: nchanl, nsig
+integer(i_kind), intent( out) :: lcloud
+real(r_kind), intent(in ) :: tsavg5, trop5
+real(r_kind), intent( out) :: cld, cldp
+real(r_kind), dimension(nchanl), intent(in ) :: tbc, ts, varinv_use
+real(r_kind), dimension(nsig,nchanl), intent(in ) :: temp
+real(r_kind), dimension(nsig), intent(in ) :: tvp, prsltmp
+
+integer(i_kind) :: i, k, kk
+
+real(r_kind) :: sum,sum2,sum3,cloudp,tmp
+real(r_kind),dimension(nchanl) :: dtb
+
+ sum3=zero
+ do i=1,nchanl
+ sum3=sum3+tbc(i)*tbc(i)*varinv_use(i)
+ end do
+ sum3=0.75_r_kind*sum3
+ lcloud=0
+ cld=zero
+ cldp=r10*prsltmp(1)
+
+ do k=1,nsig
+ if(prsltmp(k) > trop5)then
+ do i=1,nchanl
+ dtb(i)=(tvp(k)-tsavg5)*ts(i)
+ end do
+ do kk=1,k-1
+ do i=1,nchanl
+ dtb(i)=dtb(i)+(tvp(k)-tvp(kk))*temp(kk,i)
+ end do
+ end do
+ sum=zero
+ sum2=zero
+ do i=1,nchanl
+ if(varinv_use(i) > tiny_r_kind)then
+ sum=sum+tbc(i)*dtb(i)*varinv_use(i)
+ sum2=sum2+dtb(i)*dtb(i)*varinv_use(i)
+ end if
+ end do
+ if (abs(sum2) < tiny_r_kind) sum2 = sign(tiny_r_kind,sum2)
+ cloudp=min(max(sum/sum2,zero),one)
+ sum=zero
+ do i=1,nchanl
+ if(varinv_use(i) > tiny_r_kind)then
+ tmp=tbc(i)-cloudp*dtb(i)
+ sum=sum+tmp*tmp*varinv_use(i)
+ end if
+ end do
+ if(sum < sum3)then
+ sum3=sum
+ lcloud=k
+ cld=cloudp
+ cldp=r10*prsltmp(k)
+ end if
+ end if
+
+ end do
+
+end subroutine emc_legacy_cloud_detect
- return
-end subroutine qc_irsnd
subroutine qc_avhrr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
zsges,cenlat,frac_sea,pangs,trop5,tzbgr,tsavg5,tbc,tb_obs,tnoise, &
wavenumber,ptau5,prsltmp,tvp,temp,wmix,emissivity_k,ts, &
+ varinv_after_wavenum,varinv_after_rangechk,varinv_after_topo,varinv_after_transmittop, & !emily
+ varinv_after_clddet, varinv_after_nsstret, varinv_after_jsfcchk, & !emily
id_qc,aivals,errf,varinv,varinv_use,cld,cldp)
! id_qc,aivals,errf,varinv,varinv_use,cld,cldp,radmod) ! all-sky
@@ -2600,12 +2854,13 @@ subroutine qc_avhrr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
real(r_kind),dimension(nsig,nchanl),intent(in ) :: ptau5,temp,wmix
real(r_kind),dimension(nsig), intent(in ) :: prsltmp,tvp
real(r_kind),dimension(nchanl), intent(inout) :: errf,varinv,varinv_use
+ real(r_kind),dimension(nchanl), intent( out) :: varinv_after_wavenum, varinv_after_rangechk, varinv_after_topo, varinv_after_transmittop !emily
+ real(r_kind),dimension(nchanl), intent( out) :: varinv_after_clddet, varinv_after_nsstret, varinv_after_jsfcchk !emily
! Declare local parameters
real(r_kind),parameter:: oneover400=1.0_r_kind/400.0_r_kind
-
real(r_kind) :: demisf,dtempf,efact,dtbf,term,cenlatx,sfchgtfact
real(r_kind) :: sum1,sum2,sum3,cloudp,tmp,dts
real(r_kind),dimension(nchanl,nsig) :: dtb
@@ -2639,6 +2894,13 @@ subroutine qc_avhrr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
end do
endif
+!>>emily
+ do i=1,nchanl
+ varinv_after_wavenum(i) = varinv(i)
+ enddo
+!< r1000 .or. tb_obs(i) <= zero) then
varinv(i)=zero
varinv_use(i)=zero
+ if(id_qc(i) == igood_qc)id_qc(i)=ifail_range_qc !emily_bugfix
end if
+ varinv_after_rangechk(i) = varinv(i) !emily
varinv(i) = varinv(i)*(one-(one-sfchgtfact)*ptau5(1,i))
varinv_use(i) = varinv_use(i)*(one-(one-sfchgtfact)*ptau5(1,i))
+ varinv_after_topo(i) = varinv(i) !emily
! Modify error based on transmittance at top of model
varinv(i)=varinv(i)*ptau5(nsig,i)
varinv_use(i)=varinv_use(i)*ptau5(nsig,i)
errf(i)=errf(i)*ptau5(nsig,i)
+ varinv_after_transmittop(i) = varinv(i) !emily
! QC based on presence/absence of cloud
sum3=sum3+tbc(i)*tbc(i)*varinv_use(i)
@@ -2686,6 +2952,7 @@ subroutine qc_avhrr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
lcloud=0
cld=zero
cldp=r10*prsltmp(1)
+
!
! Zeroing dtb since it used outside the loop in which is defined
!
@@ -2764,6 +3031,10 @@ subroutine qc_avhrr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
end do
end if
+ do i=1,nchanl
+ varinv_after_clddet(i) = varinv(i) !emily
+ enddo
+
!
! Apply Tz retrieval
!
@@ -2791,6 +3062,10 @@ subroutine qc_avhrr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
endif
end if
+ do i=1,nchanl
+ varinv_after_nsstret(i) = varinv(i) !emily
+ enddo
+
cenlatx=abs(cenlat)*r0_04
if (cenlatx < one) then
if(luse)aivals(6,is) = aivals(6,is) + one
@@ -2809,12 +3084,17 @@ subroutine qc_avhrr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
end if
end do
+ do i=1,nchanl
+ varinv_after_jsfcchk(i) = varinv(i) !emily
+ end do
+
return
end subroutine qc_avhrr
subroutine qc_amsua(nchanl,is,ndat,nsig,npred,sea,land,ice,snow,mixed,luse, &
zsges,cenlat,tb_obsbc1,cosza,clw,tbc,ptau5,emissivity_k,ts, &
- pred,predchan,id_qc,aivals,errf,errf0,clwp_amsua,varinv,cldeff_obs,cldeff_fg,factch6, &
+ pred,predchan,id_qc,aivals,errf,errf0,clwp_amsua,varinv,varinv_sdoei,varinv_grosschk,varinv_after_jsfcchk,varinv_after_sdoei,cldeff_obs,cldeff_fg,factch6,factch4,qc4emiss_out, & !emily
+ ! pred,predchan,id_qc,aivals,errf,errf0,clwp_amsua,varinv,cldeff_obs,cldeff_fg,factch6, & !orig
cld_rbc_idx,sfc_speed,error0,clw_guess_retrieval,scatp,radmod)
!$$$ subprogram documentation block
@@ -2901,11 +3181,17 @@ subroutine qc_amsua(nchanl,is,ndat,nsig,npred,sea,land,ice,snow,mixed,luse, &
real(r_kind), intent(in ) :: cosza,clw,clwp_amsua,clw_guess_retrieval
real(r_kind), intent(in ) :: sfc_speed,scatp
real(r_kind), intent(inout) :: factch6
+ real(r_kind), intent(inout) :: factch4 !emily
+ real(r_kind), intent(inout) :: qc4emiss_out !emily
real(r_kind),dimension(40,ndat), intent(inout) :: aivals
real(r_kind),dimension(nchanl), intent(in ) :: tbc,emissivity_k,ts
real(r_kind),dimension(nsig,nchanl), intent(in ) :: ptau5
real(r_kind),dimension(npred,nchanl),intent(in ) :: pred,predchan
real(r_kind),dimension(nchanl), intent(inout) :: errf,errf0,varinv
+ real(r_kind),dimension(nchanl), intent( out) :: varinv_after_jsfcchk !emily
+ real(r_kind),dimension(nchanl), intent( out) :: varinv_after_sdoei !emily
+ real(r_kind),dimension(nchanl), intent( out) :: varinv_sdoei, varinv_grosschk !emily
+
real(r_kind),dimension(nchanl), intent(in ) :: error0
real(r_kind),dimension(nchanl), intent(in ) :: cld_rbc_idx
type(rad_obs_type), intent(in ) :: radmod
@@ -2922,7 +3208,7 @@ subroutine qc_amsua(nchanl,is,ndat,nsig,npred,sea,land,ice,snow,mixed,luse, &
real(r_kind) :: efactmc,vfactmc,dtde1,dtde2,dtde3,dtde15,dsval,clwx
real(r_kind) :: de1,de2,de3,de15
real(r_kind) :: thrd1,thrd2,thrd3,thrd15
- real(r_kind) :: factch4
+! real(r_kind) :: factch4 !emily
real(r_kind) :: ework,clwtmp
real(r_kind) :: icol
integer(i_kind) :: i
@@ -3021,17 +3307,20 @@ subroutine qc_amsua(nchanl,is,ndat,nsig,npred,sea,land,ice,snow,mixed,luse, &
errf(1:ich544)=zero
varinv(1:ich544)=zero
do i=1,ich544
- if(id_qc(i) == igood_qc)id_qc(i) = ifail_interchan_qc
+ ! if(id_qc(i) == igood_qc)id_qc(i) = ifail_interchan_qc !orig
+ if(id_qc(i) == igood_qc)id_qc(i) = ifail_range_qc !emily
end do
errf(ich890)=zero
varinv(ich890)=zero
- if(id_qc(ich890) == igood_qc) id_qc(ich890) = ifail_interchan_qc
+ ! if(id_qc(ich890) == igood_qc) id_qc(ich890) = ifail_interchan_qc !orig
+ if(id_qc(ich890) == igood_qc) id_qc(ich890) = ifail_range_qc !emily
if (latms) then
errf(16:22)=zero
varinv(16:22)=zero
do i=16,22
- if(id_qc(i) == igood_qc)id_qc(i) = ifail_interchan_qc
+ ! if(id_qc(i) == igood_qc)id_qc(i) = ifail_interchan_qc !orig
+ if(id_qc(i) == igood_qc)id_qc(i) = ifail_range_qc !emily
end do
end if
@@ -3366,6 +3655,11 @@ subroutine qc_amsua(nchanl,is,ndat,nsig,npred,sea,land,ice,snow,mixed,luse, &
end if
endif ! all-sky chk
+!>>emily
+ qc4emiss_out = zero
+ if (qc4emiss) qc4emiss_out = one
+!<>emily
+ do i = 1, nchanl
+ varinv_grosschk(i) = varinv(i)
+ enddo
+!< r2000) then
@@ -3437,6 +3737,12 @@ subroutine qc_amsua(nchanl,is,ndat,nsig,npred,sea,land,ice,snow,mixed,luse, &
end if
end do
+!>>emily
+ do i=1,nchanl
+ varinv_after_jsfcchk(i) = varinv(i) !emily
+ end do
+!<>emily
+ do i=1,nchanl
+ varinv_sdoei(i) = varinv(i) !emily
+ enddo
+!<>emily
+ do i=1,nchanl
+ varinv_after_sdoei(i) = varinv(i) !emily
+ end do
+!<>emily
+ id_qc,aivals,errf,varinv,varinv_use, &
+ varinv_after_sfcterrianchk, &
+ varinv_after_rangechk, &
+ varinv_after_topo, &
+ varinv_after_transmittop, &
+ varinv_after_clddet, &
+ varinv_after_stdchk, &
+ varinv_after_grossroutinechk, &
+ varinv_after_stdadj, &
+ varinv_after_nsstret, &
+ varinv_after_jsfcchk, &
+ cld,cldp,kmax,abi,ahi,seviri)
+!< r1000 .or. tb_obs(i) <= zero) then
varinv(i)=zero
varinv_use(i)=zero
+ if(id_qc(i) == igood_qc)id_qc(i)=ifail_range_qc !emily_bugfix
end if
+ varinv_after_rangechk(i) = varinv(i) !emily
+
tmp=one-(one-sfchgtfact)*ptau5(1,i)
varinv(i) = varinv(i)*tmp
varinv_use(i) = varinv_use(i)*tmp
+ varinv_after_topo(i) = varinv(i) !emily
! Modify error based on transmittance at top of model
varinv(i)=varinv(i)*ptau5(nsig,i)
varinv_use(i)=varinv_use(i)*ptau5(nsig,i)
errf(i)=errf(i)*ptau5(nsig,i)
+ varinv_after_transmittop(i) = varinv(i) !emily
! QC based on presence/absence of cloud
sum3=sum3+tbc(i)*tbc(i)*varinv_use(i)
@@ -4496,7 +4852,6 @@ subroutine qc_geocsr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
if(id_qc(i) == igood_qc)id_qc(i)=ifail_cloud_qc
end if
end do
-
! If no clouds check surface temperature/emissivity
else ! If no cloud was detected, do surface temp/emiss checks
sum=zero
@@ -4525,7 +4880,19 @@ subroutine qc_geocsr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
end do
end if
endif
+!>>emily
+ do i = 1, nchanl
+ varinv_after_clddet(i) = varinv(i) !emily
+ end do
+!<>emily
+ do i = 1, nchanl
+ varinv_after_stdchk(i) = varinv(i) !emily
+ varinv_after_grossroutinechk(i) = varinv(i) !emily
+ varinv_after_stdadj(i) = varinv(i) !emily
+ enddo
+!<= 0.5 for chn10.3
@@ -4546,6 +4913,7 @@ subroutine qc_geocsr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
varinv(i)=zero
end if
end if
+ varinv_after_stdchk(i) = varinv(i) !emily
! QC_o-g: If abs(o-g) > 2.0 do not use
if ( i/=2 .and. abs(tbc(i)) > two ) then
varinv(i) = zero
@@ -4553,6 +4921,7 @@ subroutine qc_geocsr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
! QC1 in statsrad
if(luse)aivals(8,is)= aivals(8,is) + one !hliu check
end if
+ varinv_after_grossroutinechk(i) = varinv(i) !emily
end if
! adjust varinv according to the BT standard deviation
@@ -4571,7 +4940,7 @@ subroutine qc_geocsr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
if(seviri .or. ahi) then
varinv(i)=varinv(i)
end if
-
+ varinv_after_stdadj(i) = varinv(i) !emily
end do
!
! Apply Tz retrieval
@@ -4600,6 +4969,12 @@ subroutine qc_geocsr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
endif
end if
+!>>emily
+ do i=1,nchanl
+ varinv_after_nsstret(i) = varinv(i) !emily
+ enddo
+!>>emily
+
! Generate q.c. bounds and modified variances.
do i=1,nchanl
if(varinv(i) > tiny_r_kind)then
@@ -4607,8 +4982,8 @@ subroutine qc_geocsr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse, &
term = dtbf*dtbf
if(term > tiny_r_kind)varinv(i)=varinv(i)/(one+varinv(i)*term)
end if
+ varinv_after_jsfcchk(i) = varinv(i) !emily
end do
-
return
@@ -4616,3 +4991,4 @@ end subroutine qc_geocsr
end module qcmod
+
diff --git a/src/gsi/radiance_mod.f90 b/src/gsi/radiance_mod.f90
index 60aa0bc3cd..aae7794957 100644
--- a/src/gsi/radiance_mod.f90
+++ b/src/gsi/radiance_mod.f90
@@ -1326,11 +1326,7 @@ subroutine radiance_ex_biascor_gmi(radmod,clw_obs,clw_guess_retrieval,nchanl,cld
do i=1,nchanl
if (radmod%lcloud4crtm(i)<0) cycle
- if (clw_obs <= cclr(i) .and. clw_guess_retrieval <= cclr(i) .and. abs(clw_obs-clw_guess_retrieval) < 0.001_r_kind) then
- cld_rbc_idx(i)=one !clear/clear
- else
- cld_rbc_idx(i)=zero
- endif
+ if ((clw_obs-cclr(i))*(clw_guess_retrieval-cclr(i))=0.005_r_kind) cld_rbc_idx(i)=zero
end do
return
diff --git a/src/gsi/radinfo.f90 b/src/gsi/radinfo.f90
index 76a08c39a5..4ad17626e6 100644
--- a/src/gsi/radinfo.f90
+++ b/src/gsi/radinfo.f90
@@ -615,7 +615,7 @@ subroutine radinfo_read
! !USES:
use obsmod, only: iout_rad
- use constants, only: zero,one,zero_quad
+ use constants, only: zero,one,zero_quad, r10
use mpimod, only: mype
use mpeu_util, only: perr,die
implicit none
@@ -855,7 +855,8 @@ subroutine radinfo_read
varA(i,j)=varx(i)
end do
ostats(j)=ostatsx
- if ((any(varx/=zero) .and. iuse_rad(j)>-2) .or. iuse_rad(j)==4) &
+ if ((all(varx==zero) .and. iuse_rad(j)>-2) .or. iuse_rad(j)==4) cycle read3
+ if ((any(varx/=r10) .and. iuse_rad(j)>-2) .or. iuse_rad(j)==4) &
inew_rad(j)=.false.
cycle read3
end if
@@ -896,7 +897,7 @@ subroutine radinfo_read
! Allocate arrays to receive angle dependent bias information.
! Open file to bias file (satang=satbias_angle). Read data.
- maxscan=250
+ maxscan=252
if (.not.adp_anglebc) maxscan = 90 ! default value for old files
if (adp_anglebc) then
@@ -1453,7 +1454,7 @@ real(r_kind) function rnad_pos(isis,iscan,jch)
piece=-0.625_r_kind
if (mod(iscan,2) == 1) piece = 0.625_r_kind
- rnad_pos=radstart(jch)+radstep(jch)*float((iscan-1)/2)+piece
+ rnad_pos=radstart(jch)+radstep(jch)*real((iscan-1)/2,r_kind)+piece
else
@@ -1465,7 +1466,7 @@ real(r_kind) function rnad_pos(isis,iscan,jch)
else
ifov=iscan
end if
- rnad_pos=radstart(jch)+radstep(jch)*float(ifov-1)
+ rnad_pos=radstart(jch)+radstep(jch)*real(ifov-1,r_kind)
end if
@@ -1740,7 +1741,7 @@ subroutine init_predx
if (.not. (any(inew_rad) .or. any(update_tlapmean))) return
if (ndat==0) return
- if (mype==0) write(6,*) 'INIT_PREDX: enter routine'
+! if (mype==0) write(6,*) 'INIT_PREDX: enter routine'
! Allocate and initialize data arrays
if (any(update_tlapmean)) then
@@ -1867,6 +1868,7 @@ subroutine init_predx
end do
end do loop_a
+ write(6,*) 'INIT_PREDX: inst_sat new_chan = ', trim(fdiag_rad), new_chan
if (.not. update .and. new_chan==0) then
call close_radiag(fdiag_rad,lndiag)
cycle loopf
@@ -2032,7 +2034,7 @@ subroutine init_predx
tlap2(jj) = tlap0(jj) + tlap1(jj)/tsum(jj)
count_tlapmean(jj)=count_tlapmean(jj)+one
elseif (tcnt(jj)>0) then
- ratio = max(zero,min(tcnt(jj)/float(nthreshold),one))
+ ratio = max(zero,min(tcnt(jj)/real(nthreshold,r_kind),one))
tsum(jj)=ratio*tsum(jj)+tsum0(jj)
! tlap2(jj) = tlap0(jj) + ratio*wgtlap*tlap1(jj)/tsum(jj)
tlap2(jj) = tlap0(jj) + ratio*tlap1(jj)/tsum(jj)
diff --git a/src/gsi/raflib.f90 b/src/gsi/raflib.f90
index 227bda3cb1..eb6d399d21 100644
--- a/src/gsi/raflib.f90
+++ b/src/gsi/raflib.f90
@@ -4488,14 +4488,14 @@ SUBROUTINE EIGEN(A,R,N,MV)
end do
if(anorm>zero) then
ANORM=1.414_r_kind*SQRT(ANORM)
- ANRMX=ANORM*RANGE/FLOAT(N)
+ ANRMX=ANORM*RANGE/real(N,r_kind)
!
! INITIALIZE INDICATORS AND COMPUTE THRESHOLD, THR
!
IND=0
THR=ANORM
loop1: do
- THR=THR/FLOAT(N)
+ THR=THR/real(N,r_kind)
loop2: do
L=1
loop3: do
diff --git a/src/gsi/rapidrefresh_cldsurf_mod.f90 b/src/gsi/rapidrefresh_cldsurf_mod.f90
index 1ee35fffba..475f44a9d3 100644
--- a/src/gsi/rapidrefresh_cldsurf_mod.f90
+++ b/src/gsi/rapidrefresh_cldsurf_mod.f90
@@ -28,7 +28,11 @@ module rapidrefresh_cldsurf_mod
! option for checking and adjusting the profile of Qr/Qs/Qg/Qnr
! retrieved through cloud analysis to reduce the background
! reflectivity ghost in analysis. (default is 0)
-!
+! 2023-07-30 Zhao added options for analysis of significant wave height
+! (SWH, aka howv in GSI code):
+! corp_howv: to set the static background error of howv
+! hwllp_howv: to set the de-correlation length scale
+! i_howv_3dda: control the analysis of howv in 3D analysis (if howv is in anavinfo)
!
! Subroutines Included:
! sub init_rapidrefresh_cldsurf - initialize RR related variables to default values
@@ -181,6 +185,42 @@ module rapidrefresh_cldsurf_mod
! = 2(clean Qg as in 1, and adjustment to the retrieved Qr/Qs/Qnr throughout the whole profile)
! = 3(similar to 2, but adjustment to Qr/Qs/Qnr only below maximum reflectivity level
! and where the dbz_obs is missing);
+! corp_howv - namelist real, static BE of howv (standard error deviation)
+! hwllp_howv - namelist real, static BE de-correlation length scale of howv
+! i_howv_3dda - integer, control the analysis of howv in 3D analysis (either var or hybrid)
+! = 0 (howv-off: default) : no analysis of howv in 3D analysis.
+! = 1 (howv-on) : if variable name "howv" is found in anavinfo,
+! set it to be 1 to turn on analysis of howv;
+! note: in hybrid envar run, the static BE is redueced by beta_s (<1.0),
+! since there is no ensemble of howv currently yet, then no ensemble
+! contribution to the total BE of howv, so the total BE of howv is actually
+! just the reduced static BE of howv. If to make the analysis of howv
+! in hyrbid run is as similar as the analysis of howv in pure 3dvar run,
+! the static BE of howv used in hybrid run needs to be tuned (inflated actually).
+! corp_gust - namelist real, static BE of gust (standard error deviation)
+! note: 1. initialised to be an arbitary negative value, in order to skip this
+! negative value, instead to use value (3.0 m/s) set in subroutine
+! berror_read_wgt_reg as default.
+! 2. (3drtma only) if a user-specified value (e.g., 2.0 m/s) is preferred
+! for corp_gust, in GSI namelist session "rapidrefresh_cldsurf",
+! set "corp_gust=2.0,"
+! hwllp_gust - namelist real, static BE de-correlation length scale of gust
+! note: 1. initialised to be an arbitary negative value, in order to skip this
+! negative value, instead to use value (same value for q) set in
+! subroutine berror_read_wgt_reg as default
+! 2. (3drtma only) if a user-specified value (e.g., 100 km) is preferred
+! for hwllp_gust, in GSI namelist session "rapidrefresh_cldsurf",
+! set "hwllp_gust=100000.0,"
+! oerr_gust - namelist real, observation error of gust
+! note: 1. initialised to be an arbitary negative value, in order to skip this
+! negative value, instead to use value (1.0 m/s) set in read_prepbufr.f90
+! 2. (3drtma only) if a user-specified value (e.g., 1.5 m/s ) is preferred
+! for oerr_gust, in GSI namelist session "rapidrefresh_cldsurf",
+! set "oerr_gust=1.5,"
+! i_gust_3dda - integer, control the analysis of gust in 3D analysis (either var or hybrid)
+! = 0 (gust-off: default) : no analysis of gust in 3D analysis.
+! = 1 (gust-on) : if variable name "gust" is found in anavinfo,
+! set it to be 1 to turn on analysis of gust;
!
! attributes:
! language: f90
@@ -252,6 +292,10 @@ module rapidrefresh_cldsurf_mod
public :: l_saturate_bkCloud
public :: l_rtma3d
public :: i_precip_vertical_check
+ public :: corp_howv, hwllp_howv
+ public :: i_howv_3dda
+ public :: corp_gust, hwllp_gust, oerr_gust
+ public :: i_gust_3dda
logical l_hydrometeor_bkio
real(r_kind) dfi_radar_latent_heat_time_period
@@ -310,6 +354,10 @@ module rapidrefresh_cldsurf_mod
logical l_saturate_bkCloud
logical l_rtma3d
integer(i_kind) i_precip_vertical_check
+ real(r_kind) :: corp_howv, hwllp_howv
+ integer(i_kind) :: i_howv_3dda
+ real(r_kind) :: corp_gust, hwllp_gust, oerr_gust
+ integer(i_kind) :: i_gust_3dda
contains
@@ -325,6 +373,8 @@ subroutine init_rapidrefresh_cldsurf
! 2008-06-03 Hu initial build for cloud analysis
! 2010-03-29 Hu change names to init_rapidrefresh_cldsurf
! 2011--5-04 Todling inquire MetGuess for presence of hyrometeors & set default
+! 2023-07-30 Zhao added code for initialization of some variables used
+! in analysis of significant wave height
!
! input argument list:
!
@@ -337,8 +387,12 @@ subroutine init_rapidrefresh_cldsurf
!$$$
use kinds, only: i_kind
use gsi_metguess_mod, only: gsi_metguess_get
+ use mpimod, only: mype
+ use state_vectors, only: ns2d,svars2d
+
implicit none
integer(i_kind) ivar,i,ier
+ integer(i_kind) i2
logical have_hmeteor(5)
character(len=2),parameter :: hydrometeors(5) = (/ 'qi', &
'ql', &
@@ -418,6 +472,41 @@ subroutine init_rapidrefresh_cldsurf
l_saturate_bkCloud= .true.
l_rtma3d = .false. ! turn configuration for rtma3d off
i_precip_vertical_check = 0 ! No check and adjustment to retrieved Qr/Qs/Qg (default)
+ corp_howv = 0.42_r_kind ! 0.42 meters (default)
+ hwllp_howv = 170000.0_r_kind ! 170,000.0 meters (170km as default for 3DRTMA, 50km is used in 2DRTMA)
+ i_howv_3dda = 0 ! no analysis of significant wave height (howv) in 3D analysis (default)
+ corp_gust = -1.50_r_kind ! initialised as negative & void to be skipped, in order to use
+ ! the value (3.0 m/s) set in sub berror_read_wgt_reg (as default).
+ ! If user-specified value is preferred, set it in session
+ ! "rapidrefresh_cldsurf" of GSI namelist file
+
+ hwllp_gust = -90000.0_r_kind ! initialised as a value, in order to skip this negative value
+ ! and to use the value (used for q) set in sub berror_read_wgt_reg.
+ ! If user-specified value is preferred, set it in session
+ ! "rapidrefresh_cldsurf" of GSI namelist file
+
+ oerr_gust = -2.5_r_kind ! initialised as a negative value, in order to skip this negative value
+ ! and to use the value (1.0 m/s) set in read_prepbufr.f90
+ ! If user-specified value is preferred, set it in session
+ ! "rapidrefresh_cldsurf" of GSI namelist file
+
+ i_gust_3dda = 0 ! no analysis of wind gust (gust) in 3D analysis (default)
+
+!-- searching for specific variable in state variable list (reading from anavinfo)
+ do i2=1,ns2d
+ if ( trim(svars2d(i2))=='howv' .or. trim(svars2d(i2))=='HOWV' ) then
+ i_howv_3dda = 1
+ if ( mype == 0 ) then
+ write(6,'(1x,A,1x,A8,1x,A,1x,I4)')"init_rapidrefresh_cldsurf: anavinfo svars2d (state variable): ",trim(adjustl(svars2d(i2))), " is found in anavinfo, set i_howv_3dda = ", i_howv_3dda
+ end if
+ end if
+ if ( trim(svars2d(i2))=='gust' .or. trim(svars2d(i2))=='GUST' ) then
+ i_gust_3dda = 1
+ if ( mype == 0 ) then
+ write(6,'(1x,A,1x,A8,1x,A,1x,I4)')"init_rapidrefresh_cldsurf: anavinfo svars2d (state variable): ",trim(adjustl(svars2d(i2))), " is found in anavinfo, set i_gust_3dda = ", i_gust_3dda
+ end if
+ end if
+ end do ! i2 : looping over 2-D anasv
return
end subroutine init_rapidrefresh_cldsurf
diff --git a/src/gsi/rdgrbsst.f90 b/src/gsi/rdgrbsst.f90
index 8be85ad608..29e5346eae 100644
--- a/src/gsi/rdgrbsst.f90
+++ b/src/gsi/rdgrbsst.f90
@@ -132,14 +132,14 @@ subroutine rdgrbsst(file_sst,mlat_sst,mlon_sst,&
! Get lat_sst & lon_sst
do i = 2, nlat_sst - 1
- rlats_sst(i) = (xsst0 + float(i-2)*dres)*deg2rad
+ rlats_sst(i) = (xsst0 + real(i-2,r_kind)*dres)*deg2rad
enddo
rlats_sst(1) = -90.0_r_kind*deg2rad
rlats_sst(nlat_sst) = 90.0_r_kind*deg2rad
do j = 2, nlon_sst - 1
- rlons_sst(j) = (ysst0 + float(j-2)*dres)*deg2rad
+ rlons_sst(j) = (ysst0 + real(j-2,r_kind)*dres)*deg2rad
enddo
rlons_sst(1) = -half*dres*deg2rad ! 1
@@ -184,8 +184,8 @@ subroutine rdgrbsst(file_sst,mlat_sst,mlon_sst,&
sums = sums + sst(j,2)
sumn = sumn + sst(j,nlat_sst-1)
end do
- sums = sums / float(i)
- sumn = sumn / float(i)
+ sums = sums / real(i,r_kind)
+ sumn = sumn / real(i,r_kind)
do j = 2,nlon_sst-1
sst(j,1) = sums
sst(j,nlat_sst) = sumn
diff --git a/src/gsi/read_NASA_LaRC_cloud.f90 b/src/gsi/read_NASA_LaRC_cloud.f90
index ec3f29e3fa..05889e2d6b 100644
--- a/src/gsi/read_NASA_LaRC_cloud.f90
+++ b/src/gsi/read_NASA_LaRC_cloud.f90
@@ -172,6 +172,13 @@ subroutine read_NASA_LaRC_cloud(nread,ndata,nouse,infile,obstype,lunout,sis,nob
write(lunout) ((cdata_all(k,i),k=1,maxdat),i=1,numobs)
write(6,*)'NASA larcglb::',nreal,numobs
+ deallocate(cdata_all)
+ deallocate(lat_l)
+ deallocate(lon_l)
+ deallocate(ptop_l)
+ deallocate(teff_l)
+ deallocate(phase_l)
+ deallocate(lwp_l)
return
end subroutine read_NASA_LaRC_cloud
diff --git a/src/gsi/read_aerosol.f90 b/src/gsi/read_aerosol.f90
index 0d07a6c904..a58b2d4358 100644
--- a/src/gsi/read_aerosol.f90
+++ b/src/gsi/read_aerosol.f90
@@ -367,7 +367,7 @@ subroutine read_aerosol(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
end if
! Deallocate local arrays
- deallocate(aeroout)
+ deallocate(aeroout,nrec)
deallocate(dataaod)
! End of MODIS bufr block
@@ -596,7 +596,8 @@ subroutine read_aerosol(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
end if
! Deallocate local arrays
- deallocate(aeroout)
+ deallocate(aeroout,nrec)
+ deallocate(dataaod)
! End of VIIRS AOD bufr block
diff --git a/src/gsi/read_airs.f90 b/src/gsi/read_airs.f90
index 16e890abd1..c5392dad14 100644
--- a/src/gsi/read_airs.f90
+++ b/src/gsi/read_airs.f90
@@ -622,7 +622,6 @@ subroutine read_airs(mype,val_airs,ithin,isfcalc,rmesh,jsatid,gstime,&
end do bufr_chans
end if
-
! Channel based quality control
if(amsua)then
@@ -790,7 +789,7 @@ subroutine read_airs(mype,val_airs,ithin,isfcalc,rmesh,jsatid,gstime,&
endif
sol_aziang = aquaspot(2)
- lza = (start + float(ifov-1)*step)*deg2rad
+ lza = (start + real(ifov-1,r_kind)*step)*deg2rad
!
! interpolate NSST variables to Obs. location and get dtw, dtc, tz_tr
!
diff --git a/src/gsi/read_amsr2.f90 b/src/gsi/read_amsr2.f90
index a7b27abccc..9d8d4944d9 100644
--- a/src/gsi/read_amsr2.f90
+++ b/src/gsi/read_amsr2.f90
@@ -566,7 +566,7 @@ subroutine read_amsr2(mype,val_amsr2,ithin,rmesh,jsatid,gstime,&
if(.not. regional .and. dist1 > 0.75_r_kind) cycle obsloop
endif
- crit1 = crit1 + 10._r_kind * float(iskip)
+ crit1 = crit1 + 10._r_kind * real(iskip,r_kind)
call checkob(dist1,crit1,itx,iuse)
if(.not. iuse) then
cycle obsloop
diff --git a/src/gsi/read_anowbufr.f90 b/src/gsi/read_anowbufr.f90
index e2b744eb6a..449ce5cdf8 100644
--- a/src/gsi/read_anowbufr.f90
+++ b/src/gsi/read_anowbufr.f90
@@ -50,7 +50,9 @@ subroutine read_anowbufr(nread,ndata,nodata,gstime,&
iconc,ierror,ilat,ilon,itime,iid,ielev,isite,iikx,ilate,ilone,&
elev_missing,site_scale,tunable_error,&
code_pm25_ncbufr,code_pm25_anowbufr,&
- code_pm10_ncbufr,code_pm10_anowbufr
+ code_pm10_ncbufr,code_pm10_anowbufr,&
+ anowbufr_ext,pm2_5_teom_max,pm10_teom_max
+
use mpimod, only: npe
implicit none
@@ -71,10 +73,12 @@ subroutine read_anowbufr(nread,ndata,nodata,gstime,&
nyob=3,ndhr=4,ntyp=5,ncopopm=6
!see headr input format below
integer(i_kind), parameter :: nfields=6
+ integer(i_kind), parameter :: nfields_b=12
!output format parameters
integer(i_kind), parameter:: nchanl=0,nreal=ilone
real(r_kind),parameter :: r360 = 360.0_r_kind
+ real(r_kind),parameter :: r90 = 90.0_r_kind
real(r_kind),parameter :: percent=1.e-2_r_kind
real(r_kind), parameter :: anow_missing=1.0e11_r_kind,&
@@ -96,8 +100,10 @@ subroutine read_anowbufr(nread,ndata,nodata,gstime,&
real(r_kind), dimension(5) :: rinc
character(len=8) :: subset
character(len=80) :: headr
+ character(len=80) :: obstr
real(r_double), dimension(nfields) :: indata
+ real(r_double), dimension(nfields_b) :: indata_a,indata_b
real(r_kind) :: tdiff,obstime,t4dv
real(r_kind) :: dlat,dlon,error_1,error_2,obserror,dlat_earth,dlon_earth
@@ -141,7 +147,6 @@ subroutine read_anowbufr(nread,ndata,nodata,gstime,&
! reading each report from bufr
do while (ireadmg(lunin,subset,idate) == 0)
-
if (trim(obstype)=='pm2_5') then
if ( (subset == 'NC008031') .or. (subset == 'NC008032' ) ) then
@@ -149,9 +154,16 @@ subroutine read_anowbufr(nread,ndata,nodata,gstime,&
ncbufr=.true.
write(6,*)'READ_PM2_5: AIRNOW data type, subset=',subset
else if (subset == 'ANOWPM') then
- headr='SID XOB YOB DHR TYP COPOPM'
- anowbufr=.true.
- write(6,*)'READ_PM2_5: AIRNOW data type, subset=',subset
+ if (anowbufr_ext) then
+ headr='SID XOB YOB DHR TYP T29 SQN PROCN RPT CAT TYPO TSIG'
+ obstr='TPHR QCIND COPOPM ELV COPOPM10 COPOCO'
+ anowbufr=.true.
+ write(6,*)'READ_PM2_5_BUFR_EXT: AIRNOW data type, subset=',subset
+ else ! default ANOWBUFR Table
+ headr='SID XOB YOB DHR TYP COPOPM'
+ anowbufr=.true.
+ write(6,*)'READ_PM2_5: AIRNOW data type, subset=',subset
+ end if
else
cycle
endif
@@ -162,6 +174,17 @@ subroutine read_anowbufr(nread,ndata,nodata,gstime,&
headr='PTID CLONH CLATH TPHR TYPO COPOPM'
ncbufr=.true.
write(6,*)'READ_PM10: AIRNOW data type, subset=',subset
+ else if (subset == 'ANOWPM') then
+ if (anowbufr_ext) then
+ headr='SID XOB YOB DHR TYP T29 SQN PROCN RPT CAT TYPO TSIG'
+ obstr='TPHR QCIND COPOPM ELV COPOPM10 COPOCO'
+ anowbufr=.true.
+ write(6,*)'READ_PM10_BUFR_EXT: AIRNOW data type, subset=',subset
+ else
+ headr='SID XOB YOB DHR TYP COPOPM'
+ anowbufr=.true.
+ write(6,*)'READ_PM10: AIRNOW data type, subset=',subset
+ end if
else
cycle
endif
@@ -176,8 +199,17 @@ subroutine read_anowbufr(nread,ndata,nodata,gstime,&
imin=0
do while (ireadsb(lunin) == 0)
- call ufbint(lunin,indata,nfields,1,iret,headr)
-
+ if (anowbufr_ext) then
+ call ufbint(lunin,indata_a,nfields_b,1,iret,headr)
+ indata(1:5) = indata_a(1:5)
+ call ufbint(lunin,indata_b,nfields_b,1,iret,obstr)
+ if (trim(obstype)=='pm2_5') indata(ncopopm)=indata_b(3)
+ if (trim(obstype)=='pm10') indata(ncopopm)=indata_b(5)
+ site_elev = indata_b(4)
+ else
+ call ufbint(lunin,indata,nfields,1,iret,headr)
+ end if
+
if (anowbufr) then
kx=indata(ntyp)
read(sid,'(Z8)')site_id
@@ -198,13 +230,15 @@ subroutine read_anowbufr(nread,ndata,nodata,gstime,&
nread = nread + 1
conc=indata(ncopopm)
-
if ( iret > 0 .and. (conc < conc_missing ) .and. &
(conc >= zero)) then
if(indata(nxob) >= r360) indata(nxob) = indata(nxob) - r360
if(indata(nxob) < zero) indata(nxob) = indata(nxob) + r360
+ if(indata(nxob) > r360)cycle
+ if(indata(nyob) > r90)cycle
+
dlon_earth_deg=indata(nxob)
dlat_earth_deg=indata(nyob)
@@ -307,6 +341,7 @@ subroutine read_anowbufr(nread,ndata,nodata,gstime,&
ndata=ndata+1
nodata=nodata+1
+ if(ndata>maxobs) exit
cdata_all(iconc,ndata) = conc ! pm2_5 obs
cdata_all(ierror,ndata) = obserror ! pm2_5 obs error
diff --git a/src/gsi/read_atms.f90 b/src/gsi/read_atms.f90
index 9f5efb5301..3ecebd32e8 100644
--- a/src/gsi/read_atms.f90
+++ b/src/gsi/read_atms.f90
@@ -177,6 +177,7 @@ subroutine read_atms(mype,val_tovs,ithin,isfcalc,&
real(r_kind), ALLOCATABLE, TARGET :: dlat_earth_save(:)
real(r_kind), ALLOCATABLE, TARGET :: crit1_save(:)
real(r_kind), ALLOCATABLE, TARGET :: lza_save(:)
+ real(r_kind), ALLOCATABLE, TARGET :: satheight_save(:)
real(r_kind), ALLOCATABLE, TARGET :: satazi_save(:)
real(r_kind), ALLOCATABLE, TARGET :: solzen_save(:)
real(r_kind), ALLOCATABLE, TARGET :: solazi_save(:)
@@ -352,6 +353,7 @@ subroutine read_atms(mype,val_tovs,ithin,isfcalc,&
ALLOCATE(crit1_save(maxobs))
ALLOCATE(it_mesh_save(maxobs))
ALLOCATE(lza_save(maxobs))
+ ALLOCATE(satheight_save(maxobs))
ALLOCATE(satazi_save(maxobs))
ALLOCATE(solzen_save(maxobs))
ALLOCATE(solazi_save(maxobs))
@@ -401,7 +403,7 @@ subroutine read_atms(mype,val_tovs,ithin,isfcalc,&
! inflate selection value for ears_db data
crit0 = 0.01_r_kind
- if ( llll > 1 ) crit0 = crit0 + r100 * float(llll)
+ if ( llll > 1 ) crit0 = crit0 + r100 * real(llll,r_kind)
call ufbint(lnbufr,bfr1bhdr,n1bhdr,1,iret,hdr1b)
@@ -455,9 +457,9 @@ subroutine read_atms(mype,val_tovs,ithin,isfcalc,&
lza = bfr2bhdr(1)*deg2rad ! local zenith angle
if(ifov <= 48) lza=-lza
- panglr=(start+float(ifov-1)*step)*deg2rad
+ panglr=(start+real(ifov-1,r_kind)*step)*deg2rad
satellite_height=bfr1bhdr(13)
-! Ensure orbit height is reasonable
+ satheight_save(iob)=satellite_height
if (satellite_height < 780000.0_r_kind .OR. &
satellite_height > 900000.0_r_kind) satellite_height = 824000.0_r_kind
rato = one + satellite_height/rearth_equator
@@ -511,10 +513,10 @@ subroutine read_atms(mype,val_tovs,ithin,isfcalc,&
ALLOCATE(Relative_Time_In_Seconds(Num_Obs))
ALLOCATE(IScan(Num_Obs))
Relative_Time_In_Seconds = 3600.0_r_kind*T4DV_Save(1:Num_Obs)
- write(6,*) 'Calling ATMS_Spatial_Average'
+! write(6,*) 'Calling ATMS_Spatial_Average'
CALL ATMS_Spatial_Average(Num_Obs, NChanl, IFOV_Save(1:Num_Obs), &
Relative_Time_In_Seconds, BT_Save(1:nchanl,1:Num_Obs), IScan, IRet)
- write(6,*) 'ATMS_Spatial_Average Called with IRet=',IRet
+! write(6,*) 'ATMS_Spatial_Average Called with IRet=',IRet
DEALLOCATE(Relative_Time_In_Seconds)
IF (IRet /= 0) THEN
@@ -534,6 +536,7 @@ subroutine read_atms(mype,val_tovs,ithin,isfcalc,&
it_mesh => it_mesh_save(iob)
ifov => ifov_save(iob)
lza => lza_save(iob)
+ satellite_height = satheight_save(iob)
satazi => satazi_save(iob)
solzen => solzen_save(iob)
solazi => solazi_save(iob)
@@ -544,11 +547,6 @@ subroutine read_atms(mype,val_tovs,ithin,isfcalc,&
dlat_earth = dlat_earth*deg2rad
dlon_earth = dlon_earth*deg2rad
-! Just use every fifth scan position and scanline (and make sure that we have
-! position 48 as we need it for scan bias)
- if (5*NINT(REAL(IScan(Iob))/5_r_kind) /= IScan(IOb) .OR. &
- 5*NINT(REAL(IFov-3)/5_r_kind) /= IFOV -3 ) CYCLE ObsLoop
-
! Regional case
if(regional)then
call tll2xy(dlon_earth,dlat_earth,dlon,dlat,outside)
@@ -648,7 +646,7 @@ subroutine read_atms(mype,val_tovs,ithin,isfcalc,&
idomsfc(1),sfcpct,ts,tsavg,vty,vfr,sty,stp,sm,sn,zz,ff10,sfcr)
endif
- crit1 = crit1 + rlndsea(isflg) + 10._r_kind*float(iskip) + 0.01_r_kind * abs(zz)
+ crit1 = crit1 + rlndsea(isflg) + 10._r_kind*real(iskip,r_kind) + 0.01_r_kind * abs(zz)
call checkob(dist1,crit1,itx,iuse)
if(.not. iuse)cycle ObsLoop
@@ -726,7 +724,7 @@ subroutine read_atms(mype,val_tovs,ithin,isfcalc,&
endif
! Re-calculate look angle
- panglr=(start+float(ifov-1)*step)*deg2rad
+ panglr=(start+real(ifov-1,r_kind)*step)*deg2rad
! Load selected observation into data array
@@ -736,7 +734,8 @@ subroutine read_atms(mype,val_tovs,ithin,isfcalc,&
data_all(3 ,itx)= dlon ! grid relative longitude
data_all(4 ,itx)= dlat ! grid relative latitude
data_all(5 ,itx)= lza ! local zenith angle
- data_all(6 ,itx)= satazi ! local azimuth angle
+ !data_all(6 ,itx)= satazi ! local azimuth angle
+ data_all(6 ,itx)= satellite_height ! temporary output
data_all(7 ,itx)= panglr ! look angle
data_all(8 ,itx)= ifovmod ! scan position
data_all(9 ,itx)= solzen ! solar zenith angle
diff --git a/src/gsi/read_avhrr.f90 b/src/gsi/read_avhrr.f90
index 48c6200c44..c1509828ad 100755
--- a/src/gsi/read_avhrr.f90
+++ b/src/gsi/read_avhrr.f90
@@ -585,6 +585,7 @@ subroutine read_avhrr(mype,val_avhrr,ithin,rmesh,jsatid,&
deallocate(data_mesh,nrec)
enddo ! do imesh = 1, nmesh
+ deallocate(amesh,hsst_thd)
! Allow single task to check for bad obs, update superobs sum,
! and write out data to scratch file for further processing.
diff --git a/src/gsi/read_bufrtovs.f90 b/src/gsi/read_bufrtovs.f90
index 0aed801ee5..d07933c133 100644
--- a/src/gsi/read_bufrtovs.f90
+++ b/src/gsi/read_bufrtovs.f90
@@ -228,7 +228,7 @@ subroutine read_bufrtovs(mype,val_tovs,ithin,isfcalc,&
real(r_kind),allocatable,dimension(:,:):: data_all
real(crtm_kind),allocatable,dimension(:):: data1b4
- real(r_double),allocatable,dimension(:):: data1b8,data1b8x
+ real(r_double),allocatable,dimension(:):: data1b8
real(r_double),dimension(n1bhdr):: bfr1bhdr
real(r_double),dimension(n2bhdr):: bfr2bhdr
@@ -519,7 +519,6 @@ subroutine read_bufrtovs(mype,val_tovs,ithin,isfcalc,&
! support multiple spc coefficient files for any given sensor
if(amsua .or. amsub .or. mhs)then
quiet=.not.verbose
- allocate(data1b8x(nchanl))
spc_coeff_versions = 0
spc_coeff_found = .true.
do while (spc_coeff_found)
@@ -674,7 +673,7 @@ subroutine read_bufrtovs(mype,val_tovs,ithin,isfcalc,&
terrain = 50._r_kind
if(llll == 1)terrain = 0.01_r_kind*abs(bfr1bhdr(13))
crit0 = 0.01_r_kind + terrain
- if (llll > 1 ) crit0 = crit0 + r100 * float(llll)
+ if (llll > 1 ) crit0 = crit0 + r100 * real(llll,r_kind)
timeinflat=two
call tdiff2crit(tdiff,ptime,ithin_time,timeinflat,crit0,crit1,it_mesh)
call map2tgrid(dlat_earth,dlon_earth,dist1,crit1,itx,ithin,itt,iuse,sis,it_mesh=it_mesh)
@@ -684,7 +683,7 @@ subroutine read_bufrtovs(mype,val_tovs,ithin,isfcalc,&
if (llll > 1) then
sacv = nint(bfr1bhdr(14))
if (sacv > spc_coeff_versions) then
- write(6,*) 'READ_BUFRTOVS WARNING sacv greater than spc_coeff_versions'
+ write(6,*) 'READ_BUFRTOVS WARNING sacv greater than spc_coeff_versions',' ',jsatid,' ',obstype
end if
else ! normal feed doesn't have antenna correction, so set sacv to 0
sacv = 0
@@ -700,7 +699,7 @@ subroutine read_bufrtovs(mype,val_tovs,ithin,isfcalc,&
if(hirs .and. ((jsatid == 'n16') .or. (jsatid == 'n17'))) &
ifovmod=ifovmod+1
- panglr=(start+float(ifovmod-1)*step)*deg2rad
+ panglr=(start+real(ifovmod-1,r_kind)*step)*deg2rad
lzaest = asin(rato*sin(panglr))
if( msu .or. hirs2 .or. ssu)then
lza = lzaest
@@ -748,13 +747,15 @@ subroutine read_bufrtovs(mype,val_tovs,ithin,isfcalc,&
! unless the satellite is n15 or n16, because tranamsua
! does this conversion because the coefficient files exist
! for it to use
- data1b8x=data1b8
data1b4=data1b8
!call apply_antcorr(accoeff_sets(spc_coeff_versions),ifov,data1b4)
call apply_antcorr(accoeff_sets(1),ifov,data1b4)
- data1b8=data1b4
do j=1,nchanl
- if(data1b8x(j) > r1000) data1b8(j) = 1000000._r_kind
+ if(data1b8(j) > r1000)then
+ data1b8(j) = 1000000._r_kind
+ else
+ data1b8(j) = data1b4(j)
+ end if
end do
end if
else ! EARS / DB
@@ -766,14 +767,16 @@ subroutine read_bufrtovs(mype,val_tovs,ithin,isfcalc,&
! data originator,
! then convert back to brightness temperature using the version
! of parameters used by the CRTM
- data1b8x=data1b8
data1b4=data1b8
call remove_antcorr(accoeff_sets(sacv),ifov,data1b4)
!call apply_antcorr(accoeff_sets(spc_coeff_versions),ifov,data1b4)
call apply_antcorr(accoeff_sets(1),ifov,data1b4)
- data1b8=data1b4
do j=1,nchanl
- if(data1b8x(j) > r1000) data1b8(j) = 1000000._r_kind
+ if(data1b8(j) > r1000) then
+ data1b8(j) = 1000000._r_kind
+ else
+ data1b8(j)=data1b4(j)
+ end if
end do
end if
end if
@@ -785,12 +788,14 @@ subroutine read_bufrtovs(mype,val_tovs,ithin,isfcalc,&
else ! EARS / DB
call ufbrep(lnbufr,data1b8,1,nchanl,iret,'TMBRST')
if ( amsua .or. amsub .or. mhs )then
- data1b8x=data1b8
data1b4=data1b8
call remove_antcorr(accoeff_sets(1),ifov,data1b4)
- data1b8=data1b4
do j=1,nchanl
- if(data1b8x(j) > r1000)data1b8(j) = 1000000._r_kind
+ if(data1b8(j) > r1000)then
+ data1b8(j) = 1000000._r_kind
+ else
+ data1b8(j) = data1b4(j)
+ end if
end do
end if
end if
@@ -816,7 +821,7 @@ subroutine read_bufrtovs(mype,val_tovs,ithin,isfcalc,&
end do
if (iskip >= nchanl) cycle read_loop
! Map obs to thinning grid
- crit1 = crit1 + 10._r_kind*float(iskip)
+ crit1 = crit1 + 10._r_kind*real(iskip,r_kind)
call checkob(dist1,crit1,itx,iuse)
if(.not. iuse)cycle read_loop
@@ -1053,8 +1058,6 @@ subroutine read_bufrtovs(mype,val_tovs,ithin,isfcalc,&
call closbf(lnbufr)
close(lnbufr)
- if (allocated(data1b8x)) deallocate(data1b8x)
-
end do ears_db_loop
deallocate(data1b8,data1b4)
@@ -1080,6 +1083,11 @@ subroutine read_bufrtovs(mype,val_tovs,ithin,isfcalc,&
call count_obs(ndata,nele,ilat,ilon,data_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon
write(lunout) ((data_all(k,n),k=1,nele),n=1,ndata)
+! write(6,*)'emily checking jsatid = ', jsatid
+! write(6,*)'emily checking nread = ', nread
+! write(6,*)'emily checking ndata = ', ndata
+! write(6,*)'emily checking ndata*nchanl = ', ndata*nchanl
+! write(6,*)'emily checking nodata = ', nodata
end if
! Deallocate local arrays
diff --git a/src/gsi/read_cris.f90 b/src/gsi/read_cris.f90
index a257480c9a..d5668f8864 100644
--- a/src/gsi/read_cris.f90
+++ b/src/gsi/read_cris.f90
@@ -93,6 +93,7 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
use gsi_nstcouplermod, only: gsi_nstcoupler_skindepth,gsi_nstcoupler_deter
use mpimod, only: npe
use gsi_io, only: verbose
+ use qcmod, only: cris_cads
! use radiance_mod, only: rad_obs_type
implicit none
@@ -145,7 +146,7 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
character(len=40) :: infile2
integer(i_kind) :: kidsat, ksatid
integer(i_kind) :: iret,ireadsb,ireadmg,irec,next, nrec_startx
- integer(i_kind) :: bufr_nchan,maxinfo
+ integer(i_kind) :: bufr_nchan,maxinfo,dval_info
integer(i_kind),allocatable,dimension(:)::nrec
@@ -178,8 +179,8 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
logical :: outside,iuse,assim,valid,clear
logical :: cris,quiet
- integer(i_kind) :: ifov, ifor, iscn, instr, ioff, ilat, ilon, sensorindex
- integer(i_kind) :: i, l, iskip, bad_line, llll
+ integer(i_kind) :: ifov, ifor, iscn, instr, ioff, ilat, ilon, sensorindex_cris
+ integer(i_kind) :: i, j, l, iskip, bad_line, llll
integer(i_kind) :: nreal, isflg
integer(i_kind) :: itx, k, nele, itt, n
integer(i_kind):: idomsfc(1)
@@ -187,7 +188,23 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
integer(i_kind):: error_status, irecx,ierr
integer(i_kind):: radedge_min, radedge_max
integer(i_kind):: bufr_size
- character(len=20),dimension(1):: sensorlist
+ character(len=20),allocatable,dimension(:) :: sensorlist
+
+! Imager cluster information for CADS
+ integer(i_kind) :: iexponent, sensorindex_imager, cads_info
+ integer(i_kind),dimension(7) :: imager_cluster_index
+ logical :: imager_coeff
+ logical,dimension(7) :: imager_cluster_flag
+ character(len=80) :: spc_filename
+ character(len=20) :: sensorlist_imager
+ real(r_kind),dimension(83,7) :: imager_info
+ real(r_kind),dimension(7) :: imager_cluster_size
+ real(r_kind),dimension(2) :: imager_mean, imager_std_dev, imager_conversion
+ real(r_kind) :: imager_cluster_tot
+
+! bufr error codes
+! real(r_kind),dimension(7,3) :: error_codes
+
! scan angle calculation geometry based on:
! C. Root 2014: JPSS Ground Project Code 474-00032
@@ -209,6 +226,7 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
! Set standard parameters
character(8),parameter:: fov_flag="crosstrk"
integer(i_kind),parameter:: sfc_channel=501 !used in thinning routine if cloud informatino is not available
+ integer(i_kind),parameter:: band_2_start=714 !for CADS, if any of band 1 (chans 1 - 713) are missing, reject profile
integer(i_kind),parameter:: ichan=-999 ! fov-based surface code is not channel specific for cris
real(r_kind),parameter:: expansion=one ! exansion factor for fov-based surface code.
! use one for ir sensors.
@@ -227,8 +245,12 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
maxinfo = 31
disterrmax=zero
ntest=0
- if(dval_use) maxinfo = maxinfo + 2
- nreal = maxinfo + nstinfo
+ dval_info = 0
+ if(dval_use) dval_info = 2
+ cads_info = 0
+ if(cris_cads) cads_info = 23
+ nreal = maxinfo + cads_info + dval_info + nstinfo
+
ndata = 0
nodata = 0
cris= obstype == 'cris' .or. obstype == 'cris-fsr'
@@ -301,46 +323,93 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
'SAID YEAR MNTH DAYS HOUR MINU SECO CLATH CLONH SAZA BEARAZ SOZA SOLAZI'
! Load spectral coefficient structure
- sensorlist(1)=sis
quiet=.not. verbose
+
+ imager_coeff = .false.
+!TODO spc_filename = trim(crtm_coeffs_path)//'viirs-m_'//trim(jsatid)//'.SpcCoeff.bin' ! when viirs naming convention becomes standarized
+ if ( trim(jsatid) == 'npp' ) then
+ spc_filename = trim(crtm_coeffs_path)//'viirs-m_npp.SpcCoeff.bin'
+ sensorlist_imager = 'viirs-m_npp'
+ elseif ( trim(jsatid) == 'n20' ) then
+ spc_filename = trim(crtm_coeffs_path)//'viirs-m_n20.SpcCoeff.bin'
+ sensorlist_imager = 'viirs-m_n20'
+ inquire(file=trim(spc_filename), exist=imager_coeff)
+ if ( .not. imager_coeff ) then
+ spc_filename = trim(crtm_coeffs_path)//'viirs-m_j1.SpcCoeff.bin'
+ sensorlist_imager = 'viirs-m_j1'
+ endif
+ elseif ( trim(jsatid) == 'n21' ) then
+ spc_filename = trim(crtm_coeffs_path)//'viirs-m_n21.SpcCoeff.bin'
+ sensorlist_imager = 'viirs-m_n21'
+ inquire(file=trim(spc_filename), exist=imager_coeff)
+ if ( .not. imager_coeff ) then
+ spc_filename = trim(crtm_coeffs_path)//'viirs-m_j2.SpcCoeff.bin'
+ sensorlist_imager = 'viirs-m_j2'
+ endif
+ endif
+ inquire(file=trim(spc_filename), exist=imager_coeff)
+ if ( imager_coeff ) then
+ allocate( sensorlist(2))
+ sensorlist(1) = sis
+!TODO sensorlist(2) = 'viirs-m_'//trim(jsatid) !when viirs naming conventions becomes standardized
+ sensorlist(2) = trim(sensorlist_imager)
+ else
+ allocate( sensorlist(1))
+ sensorlist(1) = sis
+ endif
+
if( crtm_coeffs_path /= "" ) then
if(mype_sub==mype_root .and. print_verbose) write(6,*)'READ_CRIS: crtm_spccoeff_load() on path "'//trim(crtm_coeffs_path)//'"'
error_status = crtm_spccoeff_load(sensorlist,&
- File_Path = crtm_coeffs_path,quiet=quiet )
+ File_Path = crtm_coeffs_path,quiet=quiet)
else
error_status = crtm_spccoeff_load(sensorlist,quiet=quiet)
endif
if (error_status /= success) then
write(6,*)'READ_CRIS: ***ERROR*** crtm_spccoeff_load error_status=',error_status,&
- ' TERMINATE PROGRAM EXECUTION'
+ ' TERMINATE PROGRAM EXECUTION'
call stop2(71)
endif
+! find CRIS sensorindex.
+ sensorindex_cris = 0
+ if ( sc(1)%sensor_id(1:4) == 'cris' )then
+ sensorindex_cris = 1
+ else
+ write(6,*)'READ_CRIS: ***ERROR*** sensorindex_cris not set NO CRIS DATA USED'
+ write(6,*)'READ_CRIS: We are looking for ', sc(1)%sensor_id, ' TERMINATE PROGRAM EXECUTION'
+ call stop2(71)
+ end if
+
+! find imager sensorindex.
+ sensorindex_imager = 0
+ if ( cris_cads .and. imager_coeff ) then
+ if ( sc(2)%sensor_id(1:4) == 'viir' )then
+ sensorindex_imager = 2
+ else
+ write(6,*)'READ_CRIS: ***ERROR*** sensorindex_viirs not set NO VIIRS CLUSTER INFO USED BY CADS'
+ write(6,*)'READ_CRIS: We are looking for ', sc(2)%sensor_id, ' TERMINATE PROGRAM EXECUTION'
+ imager_coeff = .false.
+ end if
+ else
+ imager_coeff = .false.
+ end if
+
! Find the channels being used (from satinfo file) in the spectral coef. structure.
do i=subset_start,subset_end
channel_number(i -subset_start +1) = nuchan(i)
end do
sc_index(:) = 0
satinfo_chan: do i=1,satinfo_nchan
- spec_coef: do l=1,sc(1)%n_channels
- if ( channel_number(i) == sc(1)%sensor_channel(l) ) then
+ spec_coef: do l=1,sc(sensorindex_cris)%n_channels
+ if ( channel_number(i) == sc(sensorindex_cris)%sensor_channel(l) ) then
sc_index(i) = l
exit spec_coef
endif
end do spec_coef
end do satinfo_chan
-! find CRIS sensorindex.
- sensorindex = 0
- if ( sc(1)%sensor_id(1:4) == 'cris' )then
- sensorindex = 1
- else
- write(6,*)'READ_CRIS: ***ERROR*** sensorindex not set NO CRIS DATA USED'
- write(6,*)'READ_CRIS: We are looking for ', sc(1)%sensor_id, ' TERMINATE PROGRAM EXECUTION'
- call stop2(71)
- end if
-
! Calculate parameters needed for FOV-based surface calculation.
if (isfcalc==1)then
instr=17 ! CrIS is similar to AIRS for this purpose.
@@ -582,7 +651,7 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
! Increment nread counter by bufr_nchan (should be changed to number of channels in satinfo file? (satinfo_nchan))
nread = nread + satinfo_nchan
crit0 = 0.01_r_kind
- if( llll > 1 ) crit0 = crit0 + r100 * float(llll)
+ if( llll > 1 ) crit0 = crit0 + r100 * real(llll,r_kind)
timeinflat=6.0_r_kind
call tdiff2crit(tdiff,ptime,ithin_time,timeinflat,crit0,crit1,it_mesh)
call map2tgrid(dlat_earth,dlon_earth,dist1,crit1,itx,ithin,itt,iuse,sis,it_mesh=it_mesh)
@@ -600,8 +669,8 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
if( ifor <= 15 ) sat_zenang = -sat_zenang
! Compute scan angle including sensor twist.
- look_angle_est = (start + float((ifor-1))*step) * deg2rad + &
- fov_dist(ifov) * sin(fov_ang(ifov) - float(ifor-1)*step*deg2rad)
+ look_angle_est = (start + real((ifor-1),r_kind)*step) * deg2rad + &
+ fov_dist(ifov) * sin(fov_ang(ifov) - real(ifor-1,r_kind)*step*deg2rad)
sat_look_angle=asin(rato*sin(sat_zenang*deg2rad))
if(abs(sat_look_angle)*rad2deg > MAX_SENSOR_ZENITH_ANGLE) then
@@ -687,7 +756,7 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
clear = .false.
pred = zero
-! Cloud information may be missing depending on how the VIIRS granules align
+! Cloud information may be missing depending on how the imager granules align
! with the CrIS granules.
! Cloud Amount, TOCC is total cloud cover [%], HOCT is cloud height [m]
call ufbint(lnbufr,cloud_properties,2,1,iret,'TOCC HOCT')
@@ -699,7 +768,7 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
else
pred1 = cloud_properties(2) *7.0_r_kind / r1000 ! Assume a lapse rate to convert hgt to delta TB.
radiance = allchan(2,sfc_channel_index) * r1000 ! Conversion from W to mW
- call crtm_planck_temperature(sensorindex,sfc_channel,radiance,temperature(sfc_channel_index)) ! radiance to BT calculation
+ call crtm_planck_temperature(sensorindex_cris,sfc_channel,radiance,temperature(sfc_channel_index)) ! radiance to BT calculation
pred2 = tsavg *0.98_r_kind - temperature(sfc_channel_index)
pred = max(pred1,pred2) ! use the largest of lapse rate (pred1) or sfc channel-surface difference (pred2)
endif
@@ -709,7 +778,7 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
! the surface channel is fixed and set earlier in the code (501).
radiance = allchan(2,sfc_channel_index) * r1000 ! Conversion from W to mW
- call crtm_planck_temperature(sensorindex,sfc_channel,radiance,temperature(sfc_channel_index)) ! radiance to BT calculation
+ call crtm_planck_temperature(sensorindex_cris,sfc_channel,radiance,temperature(sfc_channel_index)) ! radiance to BT calculation
if (temperature(sfc_channel_index) > tbmin .and. temperature(sfc_channel_index) < tbmax ) then
if ( tsavg*0.98_r_kind <= temperature(sfc_channel_index)) then ! 0.98 is a crude estimate of the surface emissivity
clear = .true.
@@ -743,7 +812,7 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
! now such spectra are rejected.
if (( allchan(2,bufr_chan) > zero .and. allchan(2,bufr_chan) < 99999._r_kind)) then ! radiance bounds
radiance = allchan(2,bufr_chan) * r1000 ! Conversion from W to mW
- call crtm_planck_temperature(sensorindex,sc_chan,radiance,temperature(bufr_chan)) ! radiance to BT calculation
+ call crtm_planck_temperature(sensorindex_cris,sc_chan,radiance,temperature(bufr_chan)) ! radiance to BT calculation
else ! error with channel number or radiance
temperature(bufr_chan) = tbmin
endif
@@ -756,14 +825,14 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
bufr_chan = bufr_index(i)
if(temperature(bufr_chan) <= tbmin .or. temperature(bufr_chan) >= tbmax ) then
temperature(bufr_chan) = tbmin
- if(iuse_rad(ioff+i) >= 0) iskip = iskip + 1
+ if(iuse_rad(ioff+i) >= 0 .or. (cris_cads .and. sc_index(i) < band_2_start)) iskip = iskip + 1
endif
end do skip_loop
if(iskip > 0 .and. print_verbose)write(6,*) ' READ_CRIS : iskip > 0 ',iskip
-! if( iskip >= 10 )cycle read_loop
+ if( iskip >= 10 .and. cris_cads ) cycle read_loop
- crit1=crit1 + ten*float(iskip)
+ crit1=crit1 + ten*real(iskip,r_kind)
! Final map obs to grids
if ( clear ) then
@@ -772,9 +841,86 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
call finalcheck(one,crit1,itx,iuse)
endif
if(.not. iuse)cycle read_loop
-!
+
+! Read the imager cluster information for the Cloud and Aerosol Detection Software.
+! Only channels 15 and 16 are used.
+
+ if ( cris_cads ) then
+ call ufbseq(lnbufr,imager_info,83,7,iret,'CRISCS')
+ if ( iret == 7 .and. imager_info(3,1) <= 100.0_r_kind .and. &
+ imager_info(3,1) >= zero .and. imager_coeff ) then ! if imager cluster info exists
+ imager_mean = zero
+ imager_std_dev = zero
+ imager_cluster_tot = zero
+ imager_cluster_flag = .TRUE.
+ imager_cluster_size = imager_info(3,1:7)
+ imager_cluster_size(:) = imager_cluster_size(:) / sum(imager_cluster_size(:))
+ imager_conversion(1) = one / (sc(sensorindex_imager)%wavenumber(4) **2)
+ imager_conversion(2) = one / (sc(sensorindex_imager)%wavenumber(5) **2)
+
+! Order clusters from largest (1) to smallest (7)
+ imager_cluster_sort: do i=1,7
+ j = maxloc(imager_cluster_size,dim=1,mask=imager_cluster_flag)
+ imager_cluster_index(i) = j
+ imager_cluster_flag(j) = .FALSE.
+ end do imager_cluster_sort
+
+! Convert from radiance to brightness temperature for mean and standard devation used by CADS
+! Imager cluster info added to data_all array.
+
+ imager_cluster_info: do j=1,7
+ i = imager_cluster_index(j)
+
+ data_all(maxinfo+j,itx) = imager_cluster_size(i) ! Imager cluster fraction
+ imager_cluster_tot = imager_cluster_tot + imager_info(3,i)
+
+ iexponent = -(nint(imager_info(75,i)) -11) ! channel 15 radiance for each cluster
+ imager_info(76,i) = imager_info(76,i) * imager_conversion(1) * (ten ** iexponent)
+
+ iexponent = -(nint(imager_info(77,i)) -11) ! channel 15 radiance std dev for each cluster.
+ imager_info(78,i) = imager_info(78,i) * imager_conversion(1) * (ten ** iexponent)
+
+ call crtm_planck_temperature(sensorindex_imager,4,imager_info(76,i),data_all(maxinfo+7+j,itx))
+ data_all(maxinfo+7+j,itx) = max(data_all(maxinfo+7+j,itx),zero)
+
+ iexponent = -(nint(imager_info(80,i)) -11) ! channel 16 radiance for each cluster
+ imager_info(81,i) = imager_info(81,i) * imager_conversion(2) * (ten ** iexponent)
+
+ iexponent = -(nint(imager_info(82,i))-5 ) ! channel 16 radiance std dev for each cluster.
+ iexponent = -(nint(imager_info(82,i)) -11) ! channel 16 radiance std dev for each cluster.
+ imager_info(83,i) = imager_info(83,i) * imager_conversion(2) * (ten ** iexponent)
+
+ call crtm_planck_temperature(sensorindex_imager,5,imager_info(81,i),data_all(maxinfo+14+j,itx))
+ data_all(maxinfo+14+j,itx) = max(data_all(maxinfo+14+j,itx),zero)
+
+
+ end do imager_cluster_info
+
+! Compute cluster averages for each channel
+
+ imager_mean(1) = sum(imager_cluster_size(:) * imager_info(76,:)) ! Channel 15 radiance cluster average
+ imager_std_dev(1) = sum(imager_cluster_size(:) * (imager_info(76,:)**2 + imager_info(78,:)**2)) - imager_mean(1)**2
+ imager_std_dev(1) = sqrt(max(imager_std_dev(1),zero)) ! Channel 15 radiance RMSE
+ call crtm_planck_temperature(sensorindex_imager,4,(imager_std_dev(1) + imager_mean(1)),imager_std_dev(1))
+ call crtm_planck_temperature(sensorindex_imager,4,imager_mean(1),imager_mean(1)) ! Channel 15 average BT
+ imager_std_dev(1) = imager_std_dev(1) - imager_mean(1) ! Channel 15 BT std dev
+ data_all(maxinfo+22,itx) = imager_std_dev(1)
+
+ imager_mean(2) = sum(imager_cluster_size(:) * imager_info(81,:)) ! Channel 16 radiance cluster average
+ imager_std_dev(2) = sum(imager_cluster_size(:) * (imager_info(81,:)**2 + imager_info(83,:)**2)) - imager_mean(1)**2
+ imager_std_dev(2) = sqrt(max(imager_std_dev(1),zero)) ! Channel 16 radiance RMSE
+ call crtm_planck_temperature(sensorindex_imager,5,(imager_std_dev(2) + imager_mean(2)),imager_std_dev(2))
+ call crtm_planck_temperature(sensorindex_imager,5,imager_mean(2),imager_mean(2)) ! Channel 16 average BT
+ imager_std_dev(2) = imager_std_dev(2) - imager_mean(2) ! Channel 16 BT std dev
+ data_all(maxinfo+23,itx) = imager_std_dev(2)
+
+ else ! Imager cluster information is missing. Set everything to zero
+ data_all(maxinfo+1 : maxinfo+25,itx) = zero
+ endif
+ endif ! cris_cads
+
! interpolate NSST variables to Obs. location and get dtw, dtc, tz_tr
-!
+
if ( nst_gsi > 0 ) then
tref = ts(0)
dtw = zero
@@ -818,15 +964,17 @@ subroutine read_cris(mype,val_cris,ithin,isfcalc,rmesh,jsatid,gstime,&
data_all(31,itx)= dlat_earth_deg ! earth relative latitude (degrees)
if(dval_use) then
- data_all(32,itx)= val_cris
- data_all(33,itx)= itt
+ data_all(maxinfo+cads_info+1,itx)= val_cris
+ data_all(maxinfo+cads_info+2,itx)= itt
+! data_all(32+cads_info,itx)= val_cris
+! data_all(33+cads_info,itx)= itt
end if
if ( nst_gsi > 0 ) then
- data_all(maxinfo+1,itx) = tref ! foundation temperature
- data_all(maxinfo+2,itx) = dtw ! dt_warm at zob
- data_all(maxinfo+3,itx) = dtc ! dt_cool at zob
- data_all(maxinfo+4,itx) = tz_tr ! d(Tz)/d(Tr)
+ data_all(maxinfo+cads_info+dval_info+1,itx) = tref ! foundation temperature
+ data_all(maxinfo+cads_info+dval_info+2,itx) = dtw ! dt_warm at zob
+ data_all(maxinfo+cads_info+dval_info+3,itx) = dtc ! dt_cool at zob
+ data_all(maxinfo+cads_info+dval_info+4,itx) = tz_tr ! d(Tz)/d(Tr)
endif
! Put satinfo defined channel temperatures into data array
diff --git a/src/gsi/read_dbz_nc.f90 b/src/gsi/read_dbz_nc.f90
index 89eebde8b6..f06545afa1 100644
--- a/src/gsi/read_dbz_nc.f90
+++ b/src/gsi/read_dbz_nc.f90
@@ -69,15 +69,16 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
use kinds, only: r_kind,r_double,i_kind,r_single
use constants, only: zero,half,one,two,deg2rad,rad2deg, &
one_tenth,r1000,r60,r60inv,r100,r400,grav_equator, &
- eccentricity,somigliana,grav_ratio,grav,semi_major_axis,flattening
+ eccentricity,somigliana,grav_ratio,grav,semi_major_axis,flattening,r_missing
use gridmod, only: tll2xy,nsig,nlat,nlon
- use obsmod, only: iadate,doradaroneob, &
+ use obsmod, only: iadate,doradaroneob,oneoblat,oneoblon,oneobheight, &
mintiltdbz,maxtiltdbz,minobrangedbz,maxobrangedbz,&
- static_gsi_nopcp_dbz,rmesh_dbz,zmesh_dbz
+ static_gsi_nopcp_dbz,rmesh_dbz,zmesh_dbz,pmot_dbz,reduce_diag
+ use gsi_4dvar, only: iwinbgn
use hybrid_ensemble_parameters,only : l_hyb_ens
use obsmod,only: radar_no_thinning,missing_to_nopcp
use convinfo, only: nconvtype,ctwind,icuse,ioctype
- use convthin, only: make3grids,map3grids,del3grids,use_all
+ use convthin, only: make3grids,map3grids_m,del3grids,use_all
use jfunc, only: miter
use mpimod, only: npe
implicit none
@@ -133,27 +134,28 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
real(r_kind), allocatable, dimension(:) :: zl_thin
real(r_kind),dimension(nsig):: hges,zges
real(r_kind) sin2,termg,termr,termrg,zobs,hgt
- integer(i_kind) ntmp,iout,iiout,ntdrvr_thin2
+ integer(i_kind) iout,ntdrvr_thin2
real(r_kind) crit1,timedif
real(r_kind),parameter:: r16000 = 16000.0_r_kind
logical :: luse
- integer(i_kind) maxout,maxdata
- integer(i_kind),allocatable,dimension(:):: isort
!--General declarations
- integer(i_kind) :: ierror,i,j,k,nvol, &
- ikx,mins_an
+ integer(i_kind) :: ierror,i,j,k,ikx,mins_an
integer(i_kind) :: maxobs,nchanl,ilat,ilon,scount
real(r_kind) :: thistiltr,thisrange,this_stahgt,thishgt
- real(r_kind) :: thisazimuthr,t4dv, &
+ real(r_kind) :: thisazimuthr, &
dlat,dlon,thiserr,thislon,thislat, &
timeb
real(r_kind) :: radartwindow
- real(r_kind) :: rmins_an
+ real(r_kind) :: rmins_an,usage
real(r_kind),allocatable,dimension(:,:):: cdata_all
real(r_double) rstation_id
+ logical, allocatable,dimension(:) :: rusage,rthin
+ logical save_all
+! integer(i_kind) numthin,numqc,numrem,numall
+ integer(i_kind) nxdata,pmot
character(8) cstaid
character(4) this_staid
@@ -217,19 +219,15 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
maxobs=50000000 !value taken from read_radar.f90
!--Allocate cdata_all array
- allocate(cdata_all(maxdat,maxobs),isort(maxobs))
- rmesh=rmesh_dbz
- zmesh=zmesh_dbz
+ allocate(cdata_all(maxdat,maxobs),rthin(maxobs),rusage(maxobs))
+ rmesh=rmesh_dbz
+ zmesh=zmesh_dbz
+ ntdrvr_thin2=0
+ icntpnt=0
+ zflag=0
- maxout=0
- maxdata=0
- isort=0
- ntdrvr_thin2=0
- icntpnt=0
- zflag=0
-
- use_all=.true.
+ use_all=.true.
if (ithin > 0) then
write(6,*)'READ_RADAR_DBZ: ithin,rmesh :',ithin,rmesh
use_all=.false.
@@ -240,7 +238,6 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
endif
xmesh=rmesh
call make3grids(xmesh,nlevz)
-! call make3grids2(xmesh,nlevz)
allocate(zl_thin(nlevz))
if (zflag == 1) then
@@ -303,6 +300,8 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
dbzQC = data_r_3d
+ deallocate(data_r_3d)
+
else if( ivar == 2 )then
allocate( data_r_1d(dims(ivar,1)) )
@@ -337,14 +336,22 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
call w3fs21(iadate,mins_an) !mins_an -integer number of mins snce 01/01/1978
rmins_an=mins_an !convert to real number
+ timeb=real(mins_an-iwinbgn,r_kind) !assume all observations are at the analysis time
ivar = 1
-
+ pmot=pmot_dbz
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
+ rusage = .true.
+ rthin = .false.
+
ILOOP : &
do i = 1, dims(ivar,1)
do j = 1, dims(ivar,2)
do k = 1, dims(ivar,3)
+
imissing2nopcp = 0
! Missing data in the input file have the value -999.0
if( dbzQC(i,j,k) <= -900.0_r_kind ) then
@@ -380,6 +387,12 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
thislon = lon(i,j)
thislat = lat(i,j)
+
+ if(doradaroneob) then
+ thislat=oneoblat
+ thislon=oneoblon
+ thishgt=oneobheight
+ endif
!-Check format of longitude and correct if necessary
@@ -404,13 +417,23 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
! changed to hard-coded value for now; dbznoise used for two different purposes in this subroutine:
! (1) threshold for lowest reflectivity value considered to be an observation and
! (2) ob error
- thiserr = 5.0_r_kind
-
-
+
+! Specify a larger error standard deviation for reflectivity observations in precipitation
+! than for reflectivity observations that indicate a lack of preciptation.
+ if( dbzQC(i,j,k) < 5.0_r_kind ) then
+ thiserr = 5.0_r_kind
+ else
+ thiserr = 10.0_r_kind
+ end if
+
nread = nread + 1
+ usage=zero
+ if(icuse(ikx) < zero)usage=r100
!#################### Data thinning ###################
icntpnt=icntpnt+1
+ if(icntpnt>maxobs) exit
+
if(ithin > 0)then
@@ -445,36 +468,28 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
zobs = hgt
- ntmp=ndata ! counting moved to map3gridS
- timedif=abs(t4dv) !don't know about this
+ timedif=zero ! assume all observations are at the analysis time
crit1 = timedif/r6+half
- call map3grids(1,zflag,zl_thin,nlevz,thislat,thislon,&
- zobs,crit1,ndata,iout,icntpnt,iiout,luse,.false.,.false.)
-
-
- maxout=max(maxout,iout)
- maxdata=max(maxdata,ndata)
-
+ call map3grids_m(1,save_all,zflag,zl_thin,nlevz, &
+ thislat,thislon,zobs,crit1,ndata,&
+ luse,maxobs,rthin,.false.,.false.)
+
if (.not. luse) then
ntdrvr_thin2=ntdrvr_thin2+1
cycle
endif
- if(iiout > 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+1
- endif
- isort(icntpnt)=iout
else
ndata =ndata+1
- nodata=nodata+1
- iout=ndata
- isort(icntpnt)=iout
endif
+ iout=ndata
!!end modified for thinning
- thisazimuthr=0.0_r_kind
+ thisazimuthr=r_missing
+ thistiltr=r_missing
+ this_stahgt=r_missing
+ thisrange=r_missing
this_staid=radid !Via equivalence in declaration, value is propagated
! to rstation_id used below.
cdata_all(1,iout) = thiserr ! reflectivity obs error (dB) - inflated/adjusted
@@ -484,7 +499,7 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
cdata_all(5,iout) = dbzQC(i,j,k) ! radar reflectivity factor
cdata_all(6,iout) = thisazimuthr ! 90deg-azimuth angle (radians)
- cdata_all(7,iout) = timeb*r60inv ! obs time (analyis relative hour)
+ cdata_all(7,iout) = timeb*r60inv ! obs time (relative hour from beginning of the DA window)
cdata_all(8,iout) = ikx ! type
cdata_all(9,iout) = thistiltr ! tilt angle (radians)
cdata_all(10,iout)= this_stahgt ! station elevation (m)
@@ -500,13 +515,57 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
cdata_all(17,iout)= dbznoise ! noise threshold for reflectivity (dBZ)
cdata_all(18,iout)= imissing2nopcp !=0, normal
!=1, !values !converted !from !missing !values
-
+ if(usage >= r100)rusage(ndata)=.false.
+
if(doradaroneob .and. (cdata_all(5,iout) > -99.0_r_kind) ) exit ILOOP
end do ! k
end do ! j
end do ILOOP ! i
+ nxdata=ndata
+ ndata=0
+ if(nxdata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,ndata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' dbz ',numall,numrem,numqc,numthin
+
+! If flag to not save thinned data is set - compress data
+ if(pmot /= 1)then
+ do i=1,nxdata
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 2 .and. (rusage(i) .and. .not. rthin(i))) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ ndata=ndata+1
+ if(i > ndata)then
+ do k=1,maxdat
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
+ end if
+ end do
+ end if
+ end if
+
+ nodata=nodata+nxdata
+
+ deallocate(dbzQC,lat,lon)
+
if (.not. use_all) then
deallocate(zl_thin)
call del3grids
@@ -514,7 +573,6 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
!---all looping done now print diagnostic output
write(6,*)'READ_dBZ: Reached eof on radar reflectivity file'
- write(6,*)'READ_dBZ: # volumes in input file =',nvol
write(6,*)'READ_dBZ: # read in obs. number =',nread
write(6,*)'READ_dBZ: # elevations outside time window =',numbadtime
write(6,*)'READ_dBZ: # of noise obs to no precip obs =',num_nopcp
@@ -533,10 +591,10 @@ subroutine read_dbz_nc(nread,ndata,nodata,infile,lunout,obstype,sis,hgtl_full,no
!---------------DEALLOCATE ARRAYS-------------!
- deallocate(cdata_all)
else !fileopen
write(6,*) 'READ_dBZ: ERROR OPENING RADAR REFLECTIVITY FILE: ',trim(infile),' IOSTAT ERROR: ',ierror, ' SKIPPING...'
end if fileopen
+deallocate(cdata_all,rusage,rthin)
end subroutine read_dbz_nc
diff --git a/src/gsi/read_dbz_netcdf.f90 b/src/gsi/read_dbz_netcdf.f90
index 6ea03afaff..193449b460 100644
--- a/src/gsi/read_dbz_netcdf.f90
+++ b/src/gsi/read_dbz_netcdf.f90
@@ -170,9 +170,9 @@ subroutine read_dbz_mrms_netcdf(nread,ndata,nodata,infile,obstype,lunout,sis,nob
integer(i_kind) :: num_missing=0,num_nopcp=0, & !counts
numbadtime=0,num_badtilt=0, &
num_badrange=0,num_m2nopcp=0, &
- num_noise=0,num_limmax=0 ,num_limmin=0
-
-
+ num_noise=0,num_limmax=0 ,num_limmin=0
+
+
!--General declarations
integer(i_kind) :: ierror,lunrad,i,j,k,v,na,nb,nelv,nvol, &
@@ -185,7 +185,7 @@ subroutine read_dbz_mrms_netcdf(nread,ndata,nodata,infile,obstype,lunout,sis,nob
real(r_kind) :: thistiltr,selev0,celev0,thisrange,this_stahgt,thishgt
real(r_kind) :: celev,selev,gamma,thisazimuthr,rlon0, &
clat0,slat0,dlat,dlon,thiserr,thislon,thislat, &
- rlonloc,rlatloc,rlonglob,rlatglob,timeb,rad_per_meter
+ rlonloc,rlatloc,rlonglob,rlatglob,timeb,rad_per_meter
real(r_kind) :: radartwindow
real(r_kind) :: dbzerr,rmins_an,rmins_ob
real(r_kind),allocatable,dimension(:,:):: cdata_all
@@ -203,7 +203,7 @@ subroutine read_dbz_mrms_netcdf(nread,ndata,nodata,infile,obstype,lunout,sis,nob
!---------SETTINGS FOR FUTURE NAMELIST---------!
integer(i_kind) :: maxobrange=999000 ! Range (m) *within* which to use observations - obs *outside* this range are not used
integer(i_kind) :: minobrange=-999 ! Range (m) *outside* of which to use observatons - obs *inside* this range are not used
- real(r_kind) :: mintilt=0.0_r_kind ! Only use tilt(elevation) angles (deg) >= this number
+ real(r_kind) :: mintilt=0.0_r_kind ! Only use tilt(elevation) angles (deg) >= this number
real(r_kind) :: maxtilt=20.0_r_kind ! Do no use tilt(elevation) angles (deg) >= this number
logical :: missing_to_nopcp=.false. ! Set missing observations to 'no precipitation' observations -> dbznoise (See Aksoy et al. 2009, MWR)
real(r_kind) :: dbznoise=2.0_r_kind ! dBZ obs must be >= dbznoise for assimilation
@@ -223,9 +223,7 @@ subroutine read_dbz_mrms_netcdf(nread,ndata,nodata,infile,obstype,lunout,sis,nob
real(r_single), allocatable :: azimuth_nc(:),beamwidth_nc(:),azimspacing_nc(:),gatewidth_nc(:)
-real(r_single), allocatable :: nyquist_nc(:),obdata_nc(:,:)
-real(r_single) nyquist_default_nc
-parameter(nyquist_default_nc=50.0_r_kind)
+real(r_single), allocatable :: obdata_nc(:,:)
!clg
! ! due to representativeness error associated with the model
!----------------------------------------------!
@@ -241,13 +239,13 @@ subroutine read_dbz_mrms_netcdf(nread,ndata,nodata,infile,obstype,lunout,sis,nob
if(trim(obstype) == trim(ioctype(i)) .and. abs(icuse(i))== 1) then
ikx=i
radartwindow=ctwind(ikx)*r60 !Time window units converted to minutes
- ! (default setting for dbz within convinfo is 0.05 hours)
- dbzerr=5_r_kind !Ob error (dB) to use for radar reflectivity factor
- exit !Exit loop when finished with initial convinfo fields
+ ! (default setting for dbz within convinfo is 0.05 hours)
+ dbzerr=5_r_kind !Ob error (dB) to use for radar reflectivity factor
+ exit !Exit loop when finished with initial convinfo fields
else if ( i==nconvtype ) then
write(6,*) 'READ_dBZ: ERROR - OBSERVATION TYPE IS NOT PRESENT IN CONVINFO OR USE FLAG IS ZERO'
- write(6,*) 'READ_dBZ: ABORTTING read_dbz.f90 - NO REFLECTIVITY OBS READ!'
- return
+ write(6,*) 'READ_dBZ: ABORTTING read_dbz.f90 - NO REFLECTIVITY OBS READ!'
+ return
endif
end do
@@ -327,7 +325,7 @@ subroutine read_dbz_mrms_netcdf(nread,ndata,nodata,infile,obstype,lunout,sis,nob
!reverse order of dimensions as stated in ncdump:
allocate(azimuth_nc(numazim_nc),beamwidth_nc(numazim_nc),azimspacing_nc(numazim_nc),gatewidth_nc(numazim_nc))
-allocate(nyquist_nc(numazim_nc),obdata_nc(numgate_nc,numazim_nc))
+allocate(obdata_nc(numgate_nc,numazim_nc))
ierr = NF90_GET_VAR(ncid,varid1,azimuth_nc)
if (ierr /= nf90_noerr) call handle_err(ierr,"azimuth data")
@@ -420,12 +418,12 @@ subroutine read_dbz_mrms_netcdf(nread,ndata,nodata,infile,obstype,lunout,sis,nob
obdate(1)=strct_in_dbz(v,k)%year
obdate(2)=strct_in_dbz(v,k)%month
- obdate(3)=strct_in_dbz(v,k)%day
+ obdate(3)=strct_in_dbz(v,k)%day
obdate(4)=strct_in_dbz(v,k)%hour
obdate(5)=strct_in_dbz(v,k)%minute
call w3fs21(obdate,mins_ob) !mins_ob -integer number of mins snce 01/01/1978
- rmins_ob=mins_ob !convert to real number
- rmins_ob=rmins_ob+(strct_in_dbz(v,k)%second*r60inv) !convert seconds to minutes and add to ob time
+ rmins_ob=mins_ob !convert to real number
+ rmins_ob=rmins_ob+(strct_in_dbz(v,k)%second*r60inv) !convert seconds to minutes and add to ob time
!-Comparison is done in units of minutes
@@ -439,139 +437,140 @@ subroutine read_dbz_mrms_netcdf(nread,ndata,nodata,infile,obstype,lunout,sis,nob
if (thistilt <= maxtilt .and. thistilt >= mintilt) then
gates: do i=1,strct_in_dbz(v,k)%num_gate
-
- thisrange=strct_in_dbz(v,k)%fstgatdis + float(i-1)*strct_in_dbz(v,k)%gateWidth
+
+ thisrange=strct_in_dbz(v,k)%fstgatdis + real(i-1,r_kind)*strct_in_dbz(v,k)%gateWidth
!-Check to make sure observations are within specified range
- if (thisrange <= maxobrange .and. thisrange >= minobrange) then
- azms: do j=1,strct_in_dbz(v,k)%num_beam
-
- !-Check to see if this is a missing observation
-
- nread=nread+1
-
+ if (thisrange <= maxobrange .and. thisrange >= minobrange) then
+ azms: do j=1,strct_in_dbz(v,k)%num_beam
+
+ !-Check to see if this is a missing observation
+
+ nread=nread+1
+
if ( abs(strct_in_dbz(v,k)%field(i,j)) >= 99.0_r_kind ) then
-
- !--Extend no precip observations to missing data fields?
+
+ !--Extend no precip observations to missing data fields?
! May help suppress spurious convection if a problem.
-
+
if (missing_to_nopcp) then
- strct_in_dbz(v,k)%field(i,j) = dbznoise
- num_m2nopcp = num_m2nopcp+1
- else
- num_missing=num_missing+1
- cycle azms !No reason to process the ob if it is missing
+ strct_in_dbz(v,k)%field(i,j) = dbznoise
+ num_m2nopcp = num_m2nopcp+1
+ else
+ num_missing=num_missing+1
+ cycle azms !No reason to process the ob if it is missing
end if
-
+
+ end if
+
+
+ if (l_limmax) then
+ if ( strct_in_dbz(v,k)%field(i,j) > 60_r_kind ) then
+ strct_in_dbz(v,k)%field(i,j) = 60_r_kind
+ num_limmax=num_limmax+1
+ end if
end if
-
-
- if (l_limmax) then
- if ( strct_in_dbz(v,k)%field(i,j) > 60_r_kind ) then
- strct_in_dbz(v,k)%field(i,j) = 60_r_kind
- num_limmax=num_limmax+1
- end if
- end if
- if (l_limmin) then
- if ( strct_in_dbz(v,k)%field(i,j) < 0_r_kind ) then
- strct_in_dbz(v,k)%field(i,j) = 0_r_kind
- num_limmin=num_limmin+1
- end if
- end if
-
- !--Find observation height using method from read_l2bufr_mod.f90
-
- this_stahgt=strct_in_dbz(v,k)%radhgt
+ if (l_limmin) then
+ if ( strct_in_dbz(v,k)%field(i,j) < 0_r_kind ) then
+ strct_in_dbz(v,k)%field(i,j) = 0_r_kind
+ num_limmin=num_limmin+1
+ end if
+ end if
+
+ !--Find observation height using method from read_l2bufr_mod.f90
+
+ this_stahgt=strct_in_dbz(v,k)%radhgt
aactual=rearth+this_stahgt
a43=four_thirds*aactual
thistiltr=thistilt*deg2rad
selev0=sin(thistiltr)
- celev0=cos(thistiltr)
- b=thisrange*(thisrange+two*aactual*selev0)
+ celev0=cos(thistiltr)
+ b=thisrange*(thisrange+two*aactual*selev0)
c=sqrt(aactual*aactual+b)
ha=b/(aactual+c)
epsh=(thisrange*thisrange-ha*ha)/(r8*aactual)
h=ha-epsh
- thishgt=this_stahgt+h
-
- !--Find observation location using method from read_l2bufr_mod.f90
-
- !-Get corrected tilt angle
- celev=celev0
- selev=selev0
- celev=a43*celev0/(a43+h)
- selev=(thisrange*thisrange+h*h+two*a43*h)/(two*thisrange*(a43+h))
-
- gamma=half*thisrange*(celev0+celev)
-
+ thishgt=this_stahgt+h
+
+ !--Find observation location using method from read_l2bufr_mod.f90
+
+ !-Get corrected tilt angle
+ celev=celev0
+ selev=selev0
+ celev=a43*celev0/(a43+h)
+ selev=(thisrange*thisrange+h*h+two*a43*h)/(two*thisrange*(a43+h))
+
+ gamma=half*thisrange*(celev0+celev)
+
!-Get earth lat lon of observation
-
+
rlon0=deg2rad*strct_in_dbz(v,k)%radlon
- clat0=cos(deg2rad*strct_in_dbz(v,k)%radlat)
- slat0=sin(deg2rad*strct_in_dbz(v,k)%radlat)
- thisazimuthr=(90.0_r_kind-strct_in_dbz(v,k)%azim(j))*deg2rad !Storing as 90-azm to
- ! be consistent with
- ! read_l2bufr_mod.f90
- rad_per_meter=one/rearth
- rlonloc=rad_per_meter*gamma*cos(thisazimuthr)
+ clat0=cos(deg2rad*strct_in_dbz(v,k)%radlat)
+ slat0=sin(deg2rad*strct_in_dbz(v,k)%radlat)
+ thisazimuthr=(90.0_r_kind-strct_in_dbz(v,k)%azim(j))*deg2rad !Storing as 90-azm to
+ ! be consistent with
+ ! read_l2bufr_mod.f90
+ rad_per_meter=one/rearth
+ rlonloc=rad_per_meter*gamma*cos(thisazimuthr)
rlatloc=rad_per_meter*gamma*sin(thisazimuthr)
-
- call invtllv(rlonloc,rlatloc,rlon0,clat0,slat0,rlonglob,rlatglob)
+
+ call invtllv(rlonloc,rlatloc,rlon0,clat0,slat0,rlonglob,rlatglob)
- thislat=rlatglob*rad2deg
+ thislat=rlatglob*rad2deg
thislon=rlonglob*rad2deg
!-Check format of longitude and correct if necessary
- if(thislon>=r360) thislon=thislon-r360
+ if(thislon>=r360) thislon=thislon-r360
if(thislon=r360 .or. thislat >90.0_r_kind) cycle
+
+ !-Convert back to radians
+
+ thislat = thislat*deg2rad
thislon = thislon*deg2rad
-
- !find grid relative lat lon locations of earth lat lon
+
+ !find grid relative lat lon locations of earth lat lon
- call tll2xy(thislon,thislat,dlon,dlat,outside)
+ call tll2xy(thislon,thislat,dlon,dlat,outside)
if (outside) cycle azms !If observation is outside the domain
- ! then cycle, but don't increase range right away.
- ! Domain could be rectangular, so ob may be out of
- ! range at one end, but not the other.
- thiserr=dbzerr
+ ! then cycle, but don't increase range right away.
+ ! Domain could be rectangular, so ob may be out of
+ ! range at one end, but not the other.
+ thiserr=dbzerr
-
- ndata = min(ndata+1,maxobs)
- nodata = min(nodata+1,maxobs) !number of obs not used (no meaning here)
-
- this_staid=strct_in_dbz(v,k)%radid !Via equivalence in declaration, value is propagated
- ! to rstation_id used below.
-
- cdata_all(1,ndata) = thiserr ! reflectivity obs error (dB) - inflated/adjusted
- cdata_all(2,ndata) = dlon ! grid relative longitude
- cdata_all(3,ndata) = dlat ! grid relative latitude
- cdata_all(4,ndata) = thishgt ! obs absolute height (m)
- cdata_all(5,ndata) = strct_in_dbz(v,k)%field(i,j) ! radar reflectivity factor
- cdata_all(6,ndata) = thisazimuthr ! 90deg-azimuth angle (radians)
- cdata_all(7,ndata) = timeb*r60inv ! obs time (analyis relative hour)
- cdata_all(8,ndata) = ikx ! type double check with the convinfo txt
- cdata_all(9,ndata) = thistiltr ! tilt angle (radians)
- cdata_all(10,ndata)= this_stahgt ! station elevation (m)
- cdata_all(11,ndata)= rstation_id ! station id
- cdata_all(12,ndata)= icuse(ikx) ! usage parameter
- cdata_all(13,ndata)= thislon*rad2deg ! earth relative longitude (degrees)
- cdata_all(14,ndata)= thislat*rad2deg ! earth relative latitude (degrees)
- cdata_all(15,ndata)= thisrange ! range from radar in m
- cdata_all(16,ndata)= dbzerr ! orginal error from convinfo file
- cdata_all(17,ndata)= dbznoise ! noise threshold for reflectivity (dBZ)
+
+ ndata = min(ndata+1,maxobs)
+ nodata = min(nodata+1,maxobs) !number of obs not used (no meaning here)
+
+ this_staid=strct_in_dbz(v,k)%radid !Via equivalence in declaration, value is propagated
+ ! to rstation_id used below.
+
+ cdata_all(1,ndata) = thiserr ! reflectivity obs error (dB) - inflated/adjusted
+ cdata_all(2,ndata) = dlon ! grid relative longitude
+ cdata_all(3,ndata) = dlat ! grid relative latitude
+ cdata_all(4,ndata) = thishgt ! obs absolute height (m)
+ cdata_all(5,ndata) = strct_in_dbz(v,k)%field(i,j) ! radar reflectivity factor
+ cdata_all(6,ndata) = thisazimuthr ! 90deg-azimuth angle (radians)
+ cdata_all(7,ndata) = timeb*r60inv ! obs time (analyis relative hour)
+ cdata_all(8,ndata) = ikx ! type double check with the convinfo txt
+ cdata_all(9,ndata) = thistiltr ! tilt angle (radians)
+ cdata_all(10,ndata)= this_stahgt ! station elevation (m)
+ cdata_all(11,ndata)= rstation_id ! station id
+ cdata_all(12,ndata)= icuse(ikx) ! usage parameter
+ cdata_all(13,ndata)= thislon*rad2deg ! earth relative longitude (degrees)
+ cdata_all(14,ndata)= thislat*rad2deg ! earth relative latitude (degrees)
+ cdata_all(15,ndata)= thisrange ! range from radar in m
+ cdata_all(16,ndata)= dbzerr ! orginal error from convinfo file
+ cdata_all(17,ndata)= dbznoise ! noise threshold for reflectivity (dBZ)
end do azms !j
else
- num_badrange=num_badrange+1 !If outside acceptable range, increment
- end if !Range check
-
- end do gates !i
+ num_badrange=num_badrange+1 !If outside acceptable range, increment
+ end if !Range check
+
+ end do gates !i
else
num_badtilt=num_badtilt+1 !If outside acceptable tilts, increment
@@ -606,18 +605,20 @@ subroutine read_dbz_mrms_netcdf(nread,ndata,nodata,infile,obstype,lunout,sis,nob
!---------------DEALLOCATE ARRAYS-------------!
- deallocate(cdata_all)
- do v=1,nvol
- do k=1,nelv
- deallocate(strct_in_dbz(v,k)%azim)
- deallocate(strct_in_dbz(v,k)%field)
- end do
- end do
- deallocate(strct_in_dbz)
else !fileopen
write(6,*) 'READ_dBZ: ERROR OPENING RADAR REFLECTIVITY FILE: ',trim(infile),' IOSTAT ERROR: ',ierror, ' SKIPPING...'
end if fileopen
+ deallocate(cdata_all)
+ do v=1,nvol
+ do k=1,nelv
+ deallocate(strct_in_dbz(v,k)%azim)
+ deallocate(strct_in_dbz(v,k)%field)
+ end do
+ end do
+ deallocate(strct_in_dbz)
+ deallocate(obdata_nc,azimuth_nc)
+ deallocate(beamwidth_nc,azimspacing_nc,gatewidth_nc)
end subroutine read_dbz_mrms_netcdf
@@ -794,9 +795,9 @@ subroutine read_dbz_mrms_sparse_netcdf(nread,ndata,nodata,infile,obstype,lunout,
integer(i_kind) :: num_missing=0,num_nopcp=0, & !counts
numbadtime=0,num_badtilt=0, &
num_badrange=0,num_m2nopcp=0, &
- num_noise=0,num_limmax=0 ,num_limmin=0
-
-
+ num_noise=0,num_limmax=0 ,num_limmin=0
+
+
!--General declarations
integer(i_kind) :: ierror,lunrad,i,j,k,v,na,nb,nelv,nvol, &
@@ -809,7 +810,7 @@ subroutine read_dbz_mrms_sparse_netcdf(nread,ndata,nodata,infile,obstype,lunout,
real(r_kind) :: thistiltr,selev0,celev0,thisrange,this_stahgt,thishgt
real(r_kind) :: celev,selev,gamma,thisazimuthr,rlon0, &
clat0,slat0,dlat,dlon,thiserr,thislon,thislat, &
- rlonloc,rlatloc,rlonglob,rlatglob,timeb,rad_per_meter
+ rlonloc,rlatloc,rlonglob,rlatglob,timeb,rad_per_meter
real(r_kind) :: radartwindow
real(r_kind) :: dbzerr,rmins_an,rmins_ob
real(r_kind),allocatable,dimension(:,:):: cdata_all
@@ -827,7 +828,7 @@ subroutine read_dbz_mrms_sparse_netcdf(nread,ndata,nodata,infile,obstype,lunout,
!---------SETTINGS FOR FUTURE NAMELIST---------!
integer(i_kind) :: maxobrange=99900000 ! Range (m) *within* which to use observations - obs *outside* this range are not used
integer(i_kind) :: minobrange=-999 ! Range (m) *outside* of which to use observatons - obs *inside* this range are not used
- real(r_kind) :: mintilt=0.0_r_kind ! Only use tilt(elevation) angles (deg) >= this number
+ real(r_kind) :: mintilt=0.0_r_kind ! Only use tilt(elevation) angles (deg) >= this number
real(r_kind) :: maxtilt=20.0_r_kind ! Do no use tilt(elevation) angles (deg) >= this number
logical :: missing_to_nopcp=.false. ! Set missing observations to 'no precipitation' observations -> dbznoise (See Aksoy et al. 2009, MWR)
real(r_kind) :: dbznoise=2_r_kind ! dBZ obs must be >= dbznoise for assimilation
@@ -849,9 +850,7 @@ subroutine read_dbz_mrms_sparse_netcdf(nread,ndata,nodata,infile,obstype,lunout,
real(r_single), allocatable :: azimuth_nc(:),beamwidth_nc(:),azimspacing_nc(:),gatewidth_nc(:)
-real(r_single), allocatable :: nyquist_nc(:),obdata_nc(:,:),obdata_pixel_nc(:)
-real(r_single) nyquist_default_nc
-parameter(nyquist_default_nc=50.0_r_kind)
+real(r_single), allocatable :: obdata_pixel_nc(:)
logical l_pixel_unlimited
integer(i_kind):: ipix
integer(i_kind)::real_numpixel,start_nc(1),count_nc(1)
@@ -863,13 +862,13 @@ subroutine read_dbz_mrms_sparse_netcdf(nread,ndata,nodata,infile,obstype,lunout,
if(trim(obstype) == trim(ioctype(i)) .and. abs(icuse(i))== 1) then
ikx=i
radartwindow=ctwind(ikx)*r60 !Time window units converted to minutes
- ! (default setting for dbz within convinfo is 0.05 hours)
- dbzerr=5_r_kind !Ob error (dB) to use for radar reflectivity factor
- exit !Exit loop when finished with initial convinfo fields
+ ! (default setting for dbz within convinfo is 0.05 hours)
+ dbzerr=5_r_kind !Ob error (dB) to use for radar reflectivity factor
+ exit !Exit loop when finished with initial convinfo fields
else if ( i==nconvtype ) then
write(6,*) 'READ_dBZ: ERROR - OBSERVATION TYPE IS NOT PRESENT IN CONVINFO OR USE FLAG IS ZERO'
- write(6,*) 'READ_dBZ: ABORTTING read_dbz.f90 - NO REFLECTIVITY OBS READ!'
- return
+ write(6,*) 'READ_dBZ: ABORTTING read_dbz.f90 - NO REFLECTIVITY OBS READ!'
+ return
endif
end do
@@ -960,7 +959,6 @@ subroutine read_dbz_mrms_sparse_netcdf(nread,ndata,nodata,infile,obstype,lunout,
!reverse order of dimensions as stated in ncdump:
allocate(azimuth_nc(numazim_nc),beamwidth_nc(numazim_nc),azimspacing_nc(numazim_nc),gatewidth_nc(numazim_nc))
-allocate(nyquist_nc(numazim_nc),obdata_nc(numgate_nc,numazim_nc))
allocate(obdata_pixel_nc(num_pixel_nc))
allocate(pixel_x_nc(num_pixel_nc))
allocate(pixel_y_nc(num_pixel_nc))
@@ -1017,20 +1015,20 @@ subroutine read_dbz_mrms_sparse_netcdf(nread,ndata,nodata,infile,obstype,lunout,
! transform the read-in ob to the intermidate obs variables( radar obs to be used in GSI
- strct_in_dbz(v,k)%radid=radarsite_nc
- strct_in_dbz(v,k)%vcpnum=vcp_nc
- strct_in_dbz(v,k)%year=iyear ! to be defind from infile name
+ strct_in_dbz(v,k)%radid=radarsite_nc
+ strct_in_dbz(v,k)%vcpnum=vcp_nc
+ strct_in_dbz(v,k)%year=iyear ! to be defind from infile name
strct_in_dbz(v,k)%month=imon
strct_in_dbz(v,k)%day=iday
strct_in_dbz(v,k)%hour=ihour
strct_in_dbz(v,k)%minute=imin
strct_in_dbz(v,k)%second=isec
- strct_in_dbz(v,k)%radlat=lat_nc
+ strct_in_dbz(v,k)%radlat=lat_nc
strct_in_dbz(v,k)%radlon=lon_nc
strct_in_dbz(v,k)%radhgt=height_nc
- strct_in_dbz(v,k)%fstgatdis =firstgate_nc
+ strct_in_dbz(v,k)%fstgatdis =firstgate_nc
strct_in_dbz(v,k)%gateWidth=gatewidth_nc(1) ! always the same ??)
- strct_in_dbz(v,k)%elev_angle=elev_nc
+ strct_in_dbz(v,k)%elev_angle=elev_nc
strct_in_dbz(v,k)%num_beam=numazim_nc
strct_in_dbz(v,k)%num_gate=numgate_nc
na=strct_in_dbz(v,k)%num_beam
@@ -1065,8 +1063,8 @@ subroutine read_dbz_mrms_sparse_netcdf(nread,ndata,nodata,infile,obstype,lunout,
obdate(5)=strct_in_dbz(v,k)%minute
call w3fs21(obdate,mins_ob) !mins_ob -integer number of mins snce 01/01/1978
- rmins_ob=mins_ob !convert to real number
- rmins_ob=rmins_ob+(strct_in_dbz(v,k)%second*r60inv) !convert seconds to minutes and add to ob time
+ rmins_ob=mins_ob !convert to real number
+ rmins_ob=rmins_ob+(strct_in_dbz(v,k)%second*r60inv) !convert seconds to minutes and add to ob time
!-Comparison is done in units of minutes
@@ -1088,139 +1086,139 @@ subroutine read_dbz_mrms_sparse_netcdf(nread,ndata,nodata,infile,obstype,lunout,
pixel: do ipix=1,real_numpixel
j=pixel_x_nc(ipix)+1
i=pixel_y_nc(ipix)+1
-
- thisrange=strct_in_dbz(v,k)%fstgatdis + float(i-1)*strct_in_dbz(v,k)%gateWidth
+
+ thisrange=strct_in_dbz(v,k)%fstgatdis + real(i-1,r_kind)*strct_in_dbz(v,k)%gateWidth
!-Check to make sure observations are within specified range
- if (thisrange <= maxobrange .and. thisrange >= minobrange) then
-
-
- nread=nread+1
+ if (thisrange <= maxobrange .and. thisrange >= minobrange) then
+
+
+ nread=nread+1
if ( abs(obdata_pixel_nc(ipix)) >= 999.0_r_kind ) then
-
- !--Extend no precip observations to missing data fields?
+
+ !--Extend no precip observations to missing data fields?
! May help suppress spurious convection if a problem.
-
+
if (missing_to_nopcp) then
- obdata_pixel_nc(ipix) = dbznoise
- num_m2nopcp = num_m2nopcp+1
- else
- num_missing=num_missing+1
- cycle pixel !No reason to process the ob if it is missing
+ obdata_pixel_nc(ipix) = dbznoise
+ num_m2nopcp = num_m2nopcp+1
+ else
+ num_missing=num_missing+1
+ cycle pixel !No reason to process the ob if it is missing
end if
-
+
+ end if
+
+
+ if (l_limmax) then
+ if ( obdata_pixel_nc(ipix) > 60_r_kind ) then
+ obdata_pixel_nc(ipix) = 60_r_kind
+ num_limmax=num_limmax+1
+ end if
end if
-
-
- if (l_limmax) then
- if ( obdata_pixel_nc(ipix) > 60_r_kind ) then
- obdata_pixel_nc(ipix) = 60_r_kind
- num_limmax=num_limmax+1
- end if
- end if
- if (l_limmin) then
- if ( obdata_pixel_nc(ipix) < 0_r_kind ) then
- obdata_pixel_nc(ipix) = 0_r_kind
- num_limmin=num_limmin+1
- end if
- end if
-
- !-Special treatment for no-precip obs?
-
-
- !--Find observation height using method from read_l2bufr_mod.f90
-
- this_stahgt=strct_in_dbz(v,k)%radhgt
+ if (l_limmin) then
+ if ( obdata_pixel_nc(ipix) < 0_r_kind ) then
+ obdata_pixel_nc(ipix) = 0_r_kind
+ num_limmin=num_limmin+1
+ end if
+ end if
+
+ !-Special treatment for no-precip obs?
+
+
+ !--Find observation height using method from read_l2bufr_mod.f90
+
+ this_stahgt=strct_in_dbz(v,k)%radhgt
aactual=rearth+this_stahgt
a43=four_thirds*aactual
thistiltr=thistilt*deg2rad
selev0=sin(thistiltr)
- celev0=cos(thistiltr)
- b=thisrange*(thisrange+two*aactual*selev0)
+ celev0=cos(thistiltr)
+ b=thisrange*(thisrange+two*aactual*selev0)
c=sqrt(aactual*aactual+b)
ha=b/(aactual+c)
epsh=(thisrange*thisrange-ha*ha)/(r8*aactual)
h=ha-epsh
- thishgt=this_stahgt+h
-
- !--Find observation location using method from read_l2bufr_mod.f90
-
- !-Get corrected tilt angle
- celev=celev0
- selev=selev0
- celev=a43*celev0/(a43+h)
- selev=(thisrange*thisrange+h*h+two*a43*h)/(two*thisrange*(a43+h))
-
- gamma=half*thisrange*(celev0+celev)
-
+ thishgt=this_stahgt+h
+
+ !--Find observation location using method from read_l2bufr_mod.f90
+
+ !-Get corrected tilt angle
+ celev=celev0
+ selev=selev0
+ celev=a43*celev0/(a43+h)
+ selev=(thisrange*thisrange+h*h+two*a43*h)/(two*thisrange*(a43+h))
+
+ gamma=half*thisrange*(celev0+celev)
+
!-Get earth lat lon of observation
-
+
rlon0=deg2rad*strct_in_dbz(v,k)%radlon
- clat0=cos(deg2rad*strct_in_dbz(v,k)%radlat)
- slat0=sin(deg2rad*strct_in_dbz(v,k)%radlat)
- thisazimuthr=(90.0_r_kind-strct_in_dbz(v,k)%azim(j))*deg2rad !Storing as 90-azm to
- ! be consistent with
- ! read_l2bufr_mod.f90
- rad_per_meter=one/rearth
- rlonloc=rad_per_meter*gamma*cos(thisazimuthr)
+ clat0=cos(deg2rad*strct_in_dbz(v,k)%radlat)
+ slat0=sin(deg2rad*strct_in_dbz(v,k)%radlat)
+ thisazimuthr=(90.0_r_kind-strct_in_dbz(v,k)%azim(j))*deg2rad !Storing as 90-azm to
+ ! be consistent with
+ ! read_l2bufr_mod.f90
+ rad_per_meter=one/rearth
+ rlonloc=rad_per_meter*gamma*cos(thisazimuthr)
rlatloc=rad_per_meter*gamma*sin(thisazimuthr)
-
- call invtllv(rlonloc,rlatloc,rlon0,clat0,slat0,rlonglob,rlatglob)
+
+ call invtllv(rlonloc,rlatloc,rlon0,clat0,slat0,rlonglob,rlatglob)
- thislat=rlatglob*rad2deg
+ thislat=rlatglob*rad2deg
thislon=rlonglob*rad2deg
!-Check format of longitude and correct if necessary
- if(thislon>=r360) thislon=thislon-r360
+ if(thislon>=r360) thislon=thislon-r360
if(thislon 0) then
+ data_extra(:,:) = diag_status%all_data_extra(diag_status%cur_ob_idx,:,:)
+ endif
diag_status%cur_ob_idx = diag_status%cur_ob_idx + 1
diff --git a/src/gsi/read_fed.f90 b/src/gsi/read_fed.f90
new file mode 100644
index 0000000000..9ba799e341
--- /dev/null
+++ b/src/gsi/read_fed.f90
@@ -0,0 +1,403 @@
+subroutine read_fed(nread,ndata,nodata,infile,obstype,lunout,twind,sis,nobs)
+!$$$ subprogram documentation block
+! . . . .
+! ABSTRACT:
+! This routine reads in netcdf or prepbufr flash-extent density (FED) data.
+!
+! PROGRAM HISTORY LOG:
+! 2018-07-25 Rong Kong (CAPS/OU) - modified based on read_radarref_mosaic.f90
+! 2019-09-20 Yaping Wang (CIMMS/OU)
+! 2021-07-01 David Dowell (DCD; NOAA GSL) - added maximum flashes/min for observed FED
+!
+! 2023-10-18 Hongli Wang (NOAA GSL)
+! - cleanup code, removed hardcoded obs height (6500m)
+! - use height fron obs file if they are avaiable, otherwise
+! use default value or value from namelist variable r_hgt_fed
+! - return if NetCDF file open status /= nf90_noerror
+!
+! input argument list:
+! infile - unit from which to read observation information file
+! obstype - observation type to process
+! lunout - unit to which to write data for further processing
+! twind - input group time window (hours)
+! sis - observation variable name
+!
+! output argument list:
+! nread - number of type "obstype" observations read
+! ndata - number of type "obstype" observations retained for further processing
+! nobs - array of observations on each subdomain for each processor
+!
+! ATTRIBUTES:
+! LANGUAGE: FORTRAN 90
+!
+!$$$
+!
+!_____________________________________________________________________
+!
+ use kinds, only: r_kind,r_double,i_kind
+ use constants, only: zero,one,deg2rad,r60inv
+ use convinfo, only: nconvtype,icuse,ioctype
+ use gsi_4dvar, only: iwinbgn
+ use gridmod, only: tll2xy
+ use mod_wrfmass_to_a, only: wrfmass_obs_to_a8
+ use mpimod, only: npe
+ use obsmod, only: perturb_obs,iadatemn,dofedoneob,oneoblat,oneoblon,r_hgt_fed
+
+ use netcdf
+ implicit none
+
+ include 'netcdf.inc'
+!
+ character(len=*), intent(in) :: infile,obstype
+ integer(i_kind), intent(in) :: lunout
+ integer(i_kind), intent(inout) :: nread,ndata
+ integer(i_kind), intent(inout) :: nodata
+ integer(i_kind), dimension(npe) ,intent(inout) :: nobs
+ real(r_kind), intent(in ) :: twind
+ character(len=*), intent(in) :: sis
+
+! Declare local parameters
+ real(r_kind),parameter:: r90 = 90.0_r_kind
+ real(r_kind),parameter:: r360 = 360.0_r_kind
+ real(r_kind),parameter:: oe_fed = 1.0_r_kind
+ real(r_kind),parameter:: fed_lowbnd = 0.1_r_kind ! use fed == fed_lowbnd
+ real(r_kind),parameter:: fed_lowbnd2 = 0.1_r_kind ! use fed >= fed_lowbnd2
+! real(r_kind),parameter:: fed_highbnd = 18.0_r_kind ! 18 flashes/min from Sebok and Back (2021, unpublished)
+ real(r_kind),parameter:: fed_highbnd = 8.0_r_kind ! 8 flashes/min from Back (2023) for regional FV3 tests
+
+!
+! For fed observations
+!
+ integer(i_kind) nreal,nchanl
+
+ integer(i_kind) ifn,i
+
+ integer(i_kind) :: ilon,ilat
+
+ logical :: fedobs, fedob
+ real(r_kind),allocatable,dimension(:,:):: cdata_out
+ real(r_kind) :: federr, thiserr
+ real(r_kind) :: hgt_fed(1)
+
+ real(r_kind) :: i_maxloc,j_maxloc,k_maxloc
+ integer(i_kind) :: kint_maxloc
+ real(r_kind) :: fed_max
+ integer(i_kind) :: ndata2
+
+ character(8) station_id
+ real(r_double) :: rstation_id
+ equivalence(rstation_id,station_id)
+
+ integer(i_kind) :: maxlvl
+ integer(i_kind) :: numfed,maxobs
+ integer(i_kind) :: k
+
+ real(r_kind),allocatable,dimension(:,:) :: fed3d_column ! 3D fed in column
+ real(r_kind),allocatable,dimension(:) :: fed3d_hgt ! fed height
+ real(r_kind),allocatable,dimension(:) :: utime ! time
+
+ integer(i_kind) :: ikx
+
+ character*128 :: myname='read_fed'
+
+ real(r_kind) :: dlat, dlon ! rotated corrdinate
+ real(r_kind) :: dlat_earth, dlon_earth ! in unit of degree
+ real(r_kind) :: rlat00, rlon00 ! in unit of rad
+
+ logical :: l_psot_fed
+ logical :: l_latlon_fedobs
+ logical :: outside
+
+! for read netcdf
+ integer(i_kind) :: sec70,mins_an
+ integer(i_kind) :: varID, ncdfID, status
+ real(r_kind) :: timeb,twindm,rmins_an,rmins_ob
+
+
+ hgt_fed = r_hgt_fed
+
+ write(6,*) "r_kind=",r_kind
+ l_psot_fed = .FALSE.
+ l_latlon_fedobs = .TRUE.
+
+ fedob = obstype == 'fed'
+ if (fedob) then
+ nreal=25
+ else
+ write(6,*) ' illegal obs type in read_fed : obstype=',obstype
+ call stop2(94)
+ end if
+ if(perturb_obs .and. fedob)nreal=nreal+1
+ write(6,*)'read_fed: nreal=',nreal
+
+ fedobs = .false.
+ ikx=0
+ do i=1,nconvtype
+ if(trim(obstype) == trim(ioctype(i)) .and. abs(icuse(i))== 1) then
+ fedobs=.true.
+ ikx=i
+ federr = oe_fed ! Obs error (flashes per minute)
+ thiserr = federr
+ exit ! Exit loop when finished with initial convinfo fields
+ else if (i == nconvtype ) then
+ write(6,*) 'read_fed: Obs Type for fed is not in CONVINFO !'
+ write(6,*) 'read_fed: PLEASE modify the CONVINFO file !'
+ write(6,*) 'read_fed: abort read_fed !'
+ return
+ endif
+ end do
+ write(6,'(1x,A,A30,I4,A15,F7.3,A7)') &
+ trim(myname),': fed in convinfo-->ikx=',ikx,' fed ob err:',thiserr," (fed)"
+
+ nread=0
+ ndata=0
+ nchanl=0
+ ifn = 15
+
+ if (fedobs) then
+ maxlvl= 1 ! fed only has one level
+
+!!!! Start reading fed observations from NETCDF format data file
+ ! CHECK IF DATA FILE EXISTS
+ ! OPEN NETCDF FILE
+ status = nf90_open(TRIM(infile), NF90_NOWRITE, ncdfID)
+ print*, '*** OPENING GOES FED OBS NETCDF FILE: ', infile, status
+ if(status/=nf90_noerr)return
+
+ !------------------------
+ ! Get Dimension Info (1-D)
+ !-------------------------
+ status = nf90_inq_varid( ncdfID, 'numobs', varID )
+ status = nf90_get_var( ncdfID, varID, maxobs )
+
+ !------------------------
+ ! Allocate data arrays
+ !-------------------------
+ ALLOCATE( fed3d_column( 5, maxobs ) )
+ allocate( fed3d_hgt(maxobs) )
+ ALLOCATE( utime( 1 ) ) ! seconds since from 2000-01-01 12:00
+ fed3d_hgt = -999.0_r_kind
+
+ !------------------------
+ ! Get useful data arrays
+ !-------------------------
+ ! LON
+ status = nf90_inq_varid( ncdfID, 'lon', varID )
+ status = nf90_get_var( ncdfID, varID, fed3d_column(1, :) )
+ ! LAT
+ status = nf90_inq_varid( ncdfID, 'lat', varID )
+ status = nf90_get_var( ncdfID, varID, fed3d_column(2, :) )
+ ! FED value
+ status = nf90_inq_varid( ncdfID, 'value', varID )
+ status = nf90_get_var( ncdfID, varID, fed3d_column(3, :) )
+ ! TIME
+ status = nf90_inq_varid( ncdfID, 'time', varID )
+ status = nf90_get_var( ncdfID, varID, utime )
+
+ ! FED height, optional variable
+ status = nf90_inq_varid( ncdfID, 'height', varID )
+ if(status==nf90_noerr)&
+ status = nf90_get_var( ncdfID, varID, fed3d_hgt )
+
+ ! CLOSE NETCDF FILE
+ status = nf90_close( ncdfID )
+
+
+ !-Obtain analysis time in minutes since reference date
+ sec70 = 694267200.0 ! seconds since from 1978-01-01 00:00 to 2000-01-01 12:00
+ ! because the official GOES prescribed epoch time for GLM data is 2000-01-01 12:00:00
+
+ call w3fs21(iadatemn,mins_an) !mins_an -integer number of mins snce 01/01/1978
+ rmins_an=mins_an !convert to real number
+
+ ! SINCE ALL OBS WILL HAVE THE SAME TIME, CHECK TIME HERE:
+ rmins_ob = ( utime(1) + sec70 )/60 !Convert to Minutes from seconds
+ twindm = twind*60. !Convert to Minutes from hours
+ timeb = rmins_ob-rmins_an
+
+ if(abs(timeb) > abs(twindm)) then
+ print*, 'WARNING: ALL FED OBSERVATIONS OUTSIDE ASSIMILATION TIME WINDOW: ', timeb, twindm
+ endif
+
+ !time relative to the beginning of the da time window
+ timeb=real(rmins_ob-iwinbgn,r_kind)
+
+ numfed = maxobs
+ do i=1,numfed
+ if (fed3d_column( 3, i ) >= fed_lowbnd2 .or. fed3d_column( 3, i ) == fed_lowbnd ) then
+ ndata = ndata + 1
+ end if
+ end do
+
+ write(6,*)'read_fed: total no. of obs = ',ndata
+ nread=ndata
+ nodata=ndata
+!!! - Finished reading fed observations from NETCDF format data file
+
+ allocate(cdata_out(nreal,ndata))
+!
+ do i=1,numfed
+ do k=1,maxlvl
+ if (fed3d_column(k+2,i) .gt. fed_highbnd) fed3d_column(k+2,i) = fed_highbnd
+ end do
+ end do
+
+ write(6,*) ' ------- check max and min value of OBS: bufr fed -------'
+ write(6,*) ' level maxval(fed) minval(fed)'
+ do k=1,maxlvl
+ write(6,*) k,maxval(fed3d_column(k+2,:)),minval(fed3d_column(k+2,:))
+ end do
+
+ i_maxloc=-1.0
+ j_maxloc=-1.0
+ k_maxloc=-1.0
+ kint_maxloc=-1
+ fed_max=-999.99
+ ndata2=0
+
+ ILOOP : &
+ do i=1,numfed
+ if(fed3d_hgt(i) > 0.0_r_kind)then
+ hgt_fed=fed3d_hgt(i)
+ else
+ hgt_fed = r_hgt_fed
+ end if
+ do k=1,maxlvl
+ if( fed3d_column(k+2,i) >= fed_lowbnd2 .or. fed3d_column(k+2,i) == fed_lowbnd .or. dofedoneob) then !Rong Kong
+ dlon_earth = fed3d_column(1,i) ! longitude (degrees) of observation
+ ! ilone=18 ! index of longitude (degrees)
+ dlat_earth = fed3d_column(2,i) ! latitude (degrees) of observation
+ ! ilate=19 ! index of latitude (degrees)
+
+ if (dofedoneob) then
+ dlat_earth=oneoblat
+ dlon_earth=oneoblon
+ endif
+
+ !-Check format of longitude and correct if necessary
+ if(dlon_earth>=r360) dlon_earth=dlon_earth-r360
+ if(dlon_earth=r360 .or. dlat_earth >90.0_r_kind) cycle
+
+ !-Convert back to radians
+ rlon00 = dlon_earth*deg2rad
+ rlat00 = dlat_earth*deg2rad
+ call tll2xy(rlon00,rlat00,dlon,dlat,outside)
+ if (dofedoneob) then
+ if (outside) then
+ write(6,*)'READ_FED: ONE OB OUTSIDE; STOP2(61) ',dlat_earth,dlon_earth
+ call stop2(61)
+ end if
+ end if
+ if (outside) cycle
+
+ !If observation is outside the domain
+ ! then cycle, but don't increase
+ ! range right away.
+ ! Domain could be rectangular, so ob
+ ! may be out of
+ ! range at one end, but not the
+ ! other.
+
+ ndata2=ndata2+1
+ cdata_out( 1,ndata2) = thiserr ! obs error (flashes/min) - inflated/adjusted
+
+ cdata_out( 2,ndata2) = dlon !
+
+ cdata_out( 3,ndata2) = dlat
+
+ cdata_out( 4,ndata2) = hgt_fed(k) ! obs absolute height (m) above MSL
+ ! ipres=4 ! index of pressure
+ cdata_out( 5,ndata2) = fed3d_column(k+2,i) ! FED value
+
+ cdata_out( 6,ndata2) = rstation_id ! station id (charstring equivalent to real double)
+ ! id=6 ! index of station id
+
+ cdata_out( 7,ndata2) = timeb*r60inv ! observation time in data array
+ ! itime=7 ! index of observation time in data array
+ cdata_out( 8,ndata2) = ikx ! ob type
+ ! ikxx=8 ! index of ob type
+ cdata_out( 9,ndata2) = thiserr*2.0_r_kind ! max error
+ ! iqmax=9 ! index of max error
+ cdata_out(10,ndata2) = 273.0_r_kind ! dry temperature
+ ! itemp=10 ! index of dry temperature
+ cdata_out(11,ndata2) = 1.0_r_kind ! quality mark
+ ! iqc=11 ! index of quality mark
+ cdata_out(12,ndata2) = thiserr ! original-original obs error ratio
+ ! ier2=12 ! index of original-original obs error ratio
+ cdata_out(13,ndata2) = icuse(ikx) ! index of use parameter
+ ! iuse=13 ! index of use parameter
+ cdata_out(14,ndata2) = icuse(ikx) ! dominant surface type
+ ! idomsfc=14 ! index of dominant surface type
+ cdata_out(15,ndata2) = 273.0_r_kind ! index of surface skin temperature
+ ! iskint=15 ! index of surface skin temperature
+ cdata_out(16,ndata2) = 0.5_r_kind ! 10 meter wind factor
+ ! iff10=16 ! index of 10 meter wind factor
+ cdata_out(17,ndata2) = 0.5_r_kind ! surface roughness
+ ! isfcr=17 ! index of surface roughness
+
+ cdata_out(18,ndata2) = dlon_earth ! longitude (degrees)
+
+ cdata_out(19,ndata2) = dlat_earth ! latitude (degrees)
+
+ cdata_out(20,ndata2) = hgt_fed(k) ! station elevation (m)
+ ! istnelv=20 ! index of station elevation (m)
+ cdata_out(21,ndata2) = hgt_fed(k) ! observation height (m)
+ ! iobshgt=21 ! index of observation height (m)
+ cdata_out(22,ndata2) = hgt_fed(k) ! surface height
+ ! izz=22 ! index of surface height
+ cdata_out(23,ndata2) = fed3d_column(4,i) ! i index of obs grid for bufr resolution (i.e.,8km)
+
+ cdata_out(24,ndata2) = fed3d_column(5,i) ! j index of obs grid for bufr resolution
+
+ cdata_out(25,ndata2) = hgt_fed(k) ! data level category
+ ! icat =25 ! index of data level category
+ if(perturb_obs .and. fedob)then
+ cdata_out(26,ndata2) = 1.0_r_kind ! obs perturbation
+ ! iptrb=26 ! index of q perturbation
+ end if
+
+ if( dofedoneob ) exit ILOOP
+
+ if(fed3d_column(k+2,i) > fed_max)then
+ kint_maxloc=k
+ k_maxloc=real(k,r_kind)
+ j_maxloc=fed3d_column(2,i)
+ i_maxloc=fed3d_column(1,i)
+ fed_max =fed3d_column(k+2,i)
+ end if
+
+ endif
+ enddo ! k
+ enddo ILOOP ! i
+
+!---all looping done now print diagnostic output
+ write(6,*)'READ_FED: Reached eof on FED file'
+ write(6,*)'READ_FED: # read in obs. number =',nread
+ write(6,*)'READ_FED: # read in obs. number for further processing =',ndata2
+! write(6,*)'READ_FED: dlon_earth', cdata_out(18,10:15)
+
+ ilon=2 ! array index for longitude
+ ilat=3 ! array index for latitude in obs information array
+ ndata=ndata2
+ nodata=ndata2
+
+!---Write observations to scratch file---!
+
+ call count_obs(ndata,nreal,ilat,ilon,cdata_out,nobs)
+ write(lunout) obstype,sis,nreal,nchanl,ilat,ilon,ndata
+ write(lunout) ((cdata_out(k,i),k=1,nreal),i=1,ndata)
+
+ deallocate(cdata_out)
+ if (allocated(fed3d_column)) deallocate(fed3d_column)
+
+ write(6,'(1x,A,F12.5,1x,A,3(1x,F8.3),1x,I4)') &
+ 'read_fed: max fed =',fed_max, '@ i j k =', &
+ i_maxloc,j_maxloc,k_maxloc,kint_maxloc
+
+ end if
+ return
+
+end subroutine read_fed
+!
+!
diff --git a/src/gsi/read_files.f90 b/src/gsi/read_files.f90
index 93ddd17bf7..60282bfbc6 100644
--- a/src/gsi/read_files.f90
+++ b/src/gsi/read_files.f90
@@ -69,7 +69,8 @@ subroutine read_files(mype)
! nfsecondn FCST Secs (i_kind) numerator
! nfsecondd FCST Secs (i_kind) denominator
!
-! %fhour = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+! %fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+! real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
! attributes:
! language: f90
@@ -264,7 +265,7 @@ subroutine read_files(mype)
write(6,*)'READ_FILES: ***WARNING*** problem reading atm file ',trim(filename),iret
idate6 = get_idate_from_time_units(atmges)
call read_vardata(atmges, 'time', fhour)
- hourg4 = float(nint(fhour(1))) ! going to make this nearest integer for now
+ hourg4 = real(nint(fhour(1)),r_kind) ! going to make this nearest integer for now
idateg(1) = idate6(4)
idateg(2) = idate6(2)
idateg(3) = idate6(3)
@@ -288,7 +289,8 @@ subroutine read_files(mype)
call stop2(80)
endif
- hourg4 = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ hourg4 = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
idateg(1) = idate(4) !hour
idateg(2) = idate(2) !month
idateg(3) = idate(3) !day
@@ -342,7 +344,7 @@ subroutine read_files(mype)
ncdim = get_dim(sfcges, 'grid_yt'); sfc_head%latb = ncdim%len
idate6 = get_idate_from_time_units(sfcges)
call read_vardata(sfcges, 'time', fhour)
- hourg4 = float(nint(fhour(1))) ! going to make this nearest integer for now
+ hourg4 = real(nint(fhour(1)),r_kind) ! going to make this nearest integer for now
idateg(1) = idate6(4)
idateg(2) = idate6(2)
idateg(3) = idate6(3)
@@ -381,7 +383,8 @@ subroutine read_files(mype)
nfhour, nfminute, nfsecondn, nfsecondd
call stop2(80)
endif
- hourg4 = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ hourg4 = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
idateg(1) = idate(4) !hour
idateg(2) = idate(2) !month
idateg(3) = idate(3) !day
@@ -478,7 +481,8 @@ subroutine read_files(mype)
nfhour, nfminute, nfsecondn, nfsecondd
call stop2(80)
endif
- hourg4 = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ hourg4 = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
idateg(1) = idate(4) !hour
idateg(2) = idate(2) !month
idateg(3) = idate(3) !day
@@ -540,7 +544,8 @@ subroutine read_files(mype)
nfhour, nfminute, nfsecondn, nfsecondd
call stop2(80)
endif
- hourg4 = float(nfhour) + float(nfminute)/r60 + float(nfsecondn)/float(nfsecondd)/r3600
+ hourg4 = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
idateg(1) = idate(4) !hour
idateg(2) = idate(2) !month
idateg(3) = idate(3) !day
@@ -585,7 +590,7 @@ subroutine read_files(mype)
if (nst_gsi > 0 ) call mpi_bcast(time_nst,2*nfldnst,mpi_rtype,npem1,mpi_comm_world,ierror)
! for external aerosol files
- if(.not.allocated(time_aer)) allocate(time_aer(nfldaer,2))
+ if(lread_ext_aerosol .and. (.not.allocated(time_aer))) allocate(time_aer(nfldaer,2))
if (lread_ext_aerosol) call mpi_bcast(time_aer,2*nfldaer,mpi_rtype,npem1,mpi_comm_world,ierror)
call mpi_bcast(iamana,3,mpi_rtype,npem1,mpi_comm_world,ierror)
@@ -620,7 +625,7 @@ subroutine read_files(mype)
endif
if (l4densvar .and. nfldsig/=ntlevs_ens) then
if (mype==0) then
- write(6,*)'READ_FILES: ***ERROR*** insufficient atm fcst for 4densvar: PROGRAM STOPS'
+ write(6,*)'READ_FILES: ***FATAL ERROR*** insufficient atm fcst for 4densvar: PROGRAM STOPS'
do i=1,ntlevs_ens
ihr=nhr_obsbin*(i-1)+nhr_half
present=.false.
@@ -629,7 +634,7 @@ subroutine read_files(mype)
end do
if (.not.present) then
write(filename,'(''sigf'',i2.2)')ihr
- write(6,*)'READ_FILES: ***ERROR*** file ',trim(filename),' missing: PROGRAM STOPS'
+ write(6,*)'READ_FILES: ***FATAL ERROR*** file ',trim(filename),' missing: PROGRAM STOPS'
endif
end do
endif
@@ -652,7 +657,7 @@ subroutine read_files(mype)
endif
if (l4densvar .and. nfldsfc/=ntlevs_ens) then
if (mype==0) then
- write(6,*)'READ_FILES: ***ERROR*** insufficient sfc fcst for 4densvar: PROGRAM STOPS'
+ write(6,*)'READ_FILES: ***FATAL ERROR*** insufficient sfc fcst for 4densvar: PROGRAM STOPS'
do i=1,ntlevs_ens
ihr=nhr_obsbin*(i-1)+nhr_half
present=.false.
@@ -661,7 +666,7 @@ subroutine read_files(mype)
end do
if (.not.present) then
write(filename,'(''sfcf'',i2.2)')ihr
- write(6,*)'READ_FILES: ***ERROR*** file ',trim(filename),' missing: PROGRAM STOPS'
+ write(6,*)'READ_FILES: ***FATAL ERROR*** file ',trim(filename),' missing: PROGRAM STOPS'
endif
end do
endif
diff --git a/src/gsi/read_fl_hdob.f90 b/src/gsi/read_fl_hdob.f90
index c7dc95f612..4041740d52 100644
--- a/src/gsi/read_fl_hdob.f90
+++ b/src/gsi/read_fl_hdob.f90
@@ -48,15 +48,15 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
use kinds, only: r_single,r_kind,r_double,i_kind
use constants, only: zero,one_tenth,one,two,ten,deg2rad,t0c,half,&
three,four,rad2deg,tiny_r_kind,huge_r_kind,r0_01,&
- r60inv,r10,r100,r2000,hvap,eps,omeps,rv,grav
+ r60inv,r10,r100,r2000,hvap,eps,omeps,rv,grav,r_missing
use gridmod, only: diagnostic_reg,regional,nlon,nlat,nsig,&
tll2xy,txy2ll,rotate_wind_ll2xy,rotate_wind_xy2ll,&
rlats,rlons,twodvar_regional,fv3_regional
use convinfo, only: nconvtype, &
icuse,ictype,icsubtype,ioctype, &
- ithin_conv,rmesh_conv,pmesh_conv
+ ithin_conv,rmesh_conv,pmesh_conv,pmot_conv
use obsmod, only: perturb_obs,perturb_fact,ran01dom
- use obsmod, only: bmiss
+ use obsmod, only: bmiss,reduce_diag
use aircraftinfo, only: aircraft_t_bc,aircraft_t_bc_pof,aircraft_t_bc_ext
use converr,only: etabl
use converr_ps,only: etabl_ps,isuble_ps,maxsub_ps
@@ -69,7 +69,7 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
use convb_uv,only: btabl_uv
use gsi_4dvar, only: l4dvar,l4densvar,iwinbgn,time_4dvar,winlen,thin4d
use qcmod, only: errormod,njqc
- use convthin, only: make3grids,map3grids,del3grids,use_all
+ use convthin, only: make3grids,map3grids_m,del3grids,use_all
use ndfdgrids,only: init_ndfdgrid,destroy_ndfdgrid,relocsfcob,adjust_error
use deter_sfc_mod, only: deter_sfc_type,deter_sfc2
use mpimod, only: npe
@@ -128,7 +128,6 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
! integer(i_kind) :: m,itypex,lcount,iflag
integer(i_kind) :: nlevp ! vertical level for thinning
integer(i_kind) :: pflag
- integer(i_kind) :: ntmp,iiout,igood
integer(i_kind) :: kk,klon1,klat1,klonp1,klatp1
integer(i_kind) :: iuse
integer(i_kind) :: nmind
@@ -137,7 +136,11 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
integer(i_kind) :: ibit(mxib)
integer(i_kind) :: idate5(5)
- integer(i_kind), allocatable,dimension(:) :: isort
+ logical, allocatable,dimension(:) :: rusage,rthin
+ logical save_all
+! integer(i_kind) numthin,numqc,numrem,numall
+ integer(i_kind) pmot,iqm
+ integer(i_kind) nxdata
! Real variables
real(r_kind), parameter :: r0_001 = 0.001_r_kind
@@ -171,7 +174,7 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
real(r_kind) :: es,qsat,rhob_calc,tdob_calc,tdry
real(r_kind) :: dummy
real(r_kind) :: del,ediff,errmin,jbmin
- real(r_kind) :: tvflg
+ real(r_kind) :: tvflg,log100
real(r_kind) :: presl(nsig)
real(r_kind) :: obstime(6,1)
@@ -188,7 +191,7 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
real(r_double) :: rstation_id
real(r_double) :: r_prvstg(1,1),r_sprvstg(1,1)
- real(r_kind), allocatable,dimension(:,:) :: cdata_all,cdata_out
+ real(r_kind), allocatable,dimension(:,:) :: cdata_all
real(r_kind), allocatable,dimension(:) :: presl_thin
! Equivalence to handle character names
@@ -234,6 +237,7 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
ierr_uv = 0
var_jb=zero
jbmin=zero
+ log100=log(100._r_kind)
lim_qm = 4
@@ -258,7 +262,7 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
else if (lpsob) then
nreal = 23
iecol = 5
- errmin = one_tenth ! set lower bound of ob error for moisture (RH)
+ errmin = one_tenth ! set lower bound of ob error for surface pressure
else
write(6,*) ' illegal obs type in read_fl_hdob '
call stop2(94)
@@ -352,6 +356,11 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
write(6,*)'READ_FL_HDOB: ictype(nc),rmesh,pflag,nlevp,pmesh,nc ',&
ioctype(nc),ictype(nc),rmesh,pflag,nlevp,pmesh,nc
endif
+ pmot=nint(pmot_conv(nc))
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
+
!------------------------------------------------------------------------------------------------
@@ -377,25 +386,25 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
!---------------------------------------------------------------------------------------------------
! Allocate array to hold data
- allocate(cdata_all(nreal,maxobs))
- allocate(isort(maxobs))
+ allocate(cdata_all(nreal,maxobs),rusage(maxobs),rthin(maxobs))
! Initialize
cdata_all = zero
- isort = 0
nread = 0
nchanl = 0
ntest = 0
nvtest = 0
ilon = 2
ilat = 3
+ rusage = .true.
+ rthin = .false.
+ use_all=.true.
! Open bufr file again for reading
open(lunin,file=trim(infile),form='unformatted')
call openbf(lunin,'IN',lunin)
call datelen(10)
ntb = 0
- igood = 0
! Loop through BUFR file
loop_msg2: do while(ireadmg(lunin,subset,idate) >= 0)
loop_readsb2: do while(ireadsb(lunin) == 0)
@@ -603,6 +612,7 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
obserr = max(obserr,errmin)
endif
! Read extrapolated surface pressure [pa] and convert to [cb]
+ dlnpsob = log100 ! default (1000mb)
if (lpsob) then
call ufbint(lunin,obspsf,1,1,nlv,psfstr)
if (obspsf(1,1) >= missing .or. &
@@ -632,7 +642,7 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
endif
enddo
if (ncount_ps ==1) then
- write(6,*) 'READ_FL_HDOB,WARNING!!psob: cannot find subtyep in the error,&
+ write(6,*) 'READ_FL_HDOB,WARNING!!psob: cannot find subtype in the error,&
table,itype,iosub=',itypey,icsubtype(nc)
write(6,*) 'read error table at colomn subtype as 0, error table column= ',ierr_ps
endif
@@ -896,9 +906,6 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
! Get information from surface file necessary for conventional data
call deter_sfc2(dlat_earth,dlon_earth,t4dv,idomsfc,tsavg,ff10,sfcr,zz)
-! Process data passed quality control
- igood = igood+1
-
! Process data thinning procedure on good data
if (ithin > 0) then
if (pflag == 0) then
@@ -922,8 +929,6 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
end do
endif ! pflag
- ntmp = ndata ! counting moved into map3grids
-
! Set data quality index for thinning
if (thin4d) then
timedif = zero
@@ -937,26 +942,18 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
end do
endif
- call map3grids(-1,pflag,presl_thin,nlevp,dlat_earth,dlon_earth,&
- pob_cb,crit1,ndata,iout,igood,iiout,luse,.false.,.false.)
+ call map3grids_m(-1,save_all,pflag,presl_thin,nlevp, &
+ dlat_earth,dlon_earth,pob_cb,crit1,ndata,&
+ luse,maxobs,rthin,.false.,.false.)
+
if (.not. luse) cycle loop_readsb2
- if(iiout > 0) isort(iiout) = 0
- if (ndata > ntmp) then
- nodata = nodata+2
- if (luvob) &
- nodata = nodata+2
- endif
- isort(igood) = iout
+ if(rthin(ndata))usage=101._r_kind
else
ndata = ndata+1
- nodata = nodata+2
- if (luvob) &
- nodata = nodata+2
- iout = ndata
- isort(igood) = iout
endif ! ithin
+ iout = ndata
!-------------------------------------------------------------------------------------------------
! Write data into output arrays
@@ -966,8 +963,11 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
if (lpsob) then
qcm = ps_qm
psoe = obserr*one_tenth ! convert from mb to cb
+ iqm=10
if (inflate_error) psoe = psoe*r1_2
- if (qcm > lim_qm ) psoe = psoe*1.0e6_r_kind
+ if (qcm > lim_qm ) then
+ psoe = psoe*1.0e6_r_kind
+ end if
cdata_all( 1,iout)=psoe ! surface pressure error (cb)
cdata_all( 2,iout)=dlon ! grid relative longitude
cdata_all( 3,iout)=dlat ! grid relative latitude
@@ -997,9 +997,12 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
! Winds --- u, v components
if (luvob) then
woe = obserr
+ iqm = 12
if (pob_mb < r50) woe = woe*r1_2
if (inflate_error) woe = woe*r1_2
- if (qcm > lim_qm ) woe = woe*1.0e6_r_kind
+ if (qcm > lim_qm ) then
+ woe = woe*1.0e6_r_kind
+ end if
if(regional .and. .not. fv3_regional)then
u0 = uob
v0 = vob
@@ -1046,9 +1049,12 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
! Temperature
if(ltob) then
toe = obserr
+ iqm = 10
if (pob_mb < r100) toe = toe*r1_2
if (inflate_error) toe = toe*r1_2
- if (qcm > lim_qm ) toe = toe*1.0e6_r_kind
+ if (qcm > lim_qm ) then
+ toe = toe*1.0e6_r_kind
+ end if
cdata_all( 1,iout)=toe ! temperature error
cdata_all( 2,iout)=dlon ! grid relative longitude
cdata_all( 3,iout)=dlat ! grid relative latitude
@@ -1081,11 +1087,14 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
if(lqob) then
qoe = obserr*one_tenth ! RH (e.g. 0.98)
qmaxerr = emerr
+ iqm = 11
if (inflate_error) then
qmaxerr = emerr*r0_7
qoe = qoe*r1_2
end if
- if (qcm > lim_qm ) qoe = qoe*1.0e6_r_kind
+ if (qcm > lim_qm ) then
+ qoe = qoe*1.0e6_r_kind
+ end if
cdata_all( 1,iout)=qoe ! q error (RH e.g. 0.98)
cdata_all( 2,iout)=dlon ! grid relative longitude
cdata_all( 3,iout)=dlat ! grid relative latitude
@@ -1116,12 +1125,15 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
! Winds --- surface wind speed
if (lspdob) then
woe = obserr
+ iqm = 11
if (inflate_error) woe = woe*r1_2
- if (qcm > lim_qm ) woe = woe*1.0e6_r_kind
+ if (qcm > lim_qm ) then
+ woe = woe*1.0e6_r_kind
+ end if
cdata_all( 1,iout)=woe ! wind error
cdata_all( 2,iout)=dlon ! grid relative longitude
cdata_all( 3,iout)=dlat ! grid relative latitude
- cdata_all( 4,iout)=dlnpsob ! ln(surface pressure in cb)
+ cdata_all( 4,iout)=r_missing ! ln(surface pressure in cb) !Since dlnpsob is not provided by SFMR, force it to be r_missing. Not used in setupspd.f90
cdata_all( 5,iout)=spdob*sqrt(two)*half ! u obs
cdata_all( 6,iout)=spdob*sqrt(two)*half ! v obs
cdata_all( 7,iout)=rstation_id ! station id
@@ -1142,6 +1154,7 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
cdata_all(22,iout)=r_prvstg(1,1) ! provider name
cdata_all(23,iout)=r_sprvstg(1,1) ! subprovider name
endif
+ if(usage >= r100)rusage(ndata)=.false.
end do loop_readsb2
end do loop_msg2
@@ -1154,31 +1167,76 @@ subroutine read_fl_hdob(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,si
deallocate(presl_thin)
call del3grids
endif
-
+
+ nxdata=ndata
+ ndata=0
+ if(nxdata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,ndata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' fl ',trim(ioctype(nc)),ictype(nc),icsubtype(nc),numall,&
+! numrem,numqc,numthin
+! If thinned data set quality mark to 14
+ if (ithin > 0 .and. ithin <5) then
+ do i=1,nxdata
+ if(rthin(i))cdata_all(iqm,i)=14
+ end do
+ end if
+
+! If flag to not save thinned data is set - compress data
+ if(pmot /= 1)then
+ do i=1,nxdata
+
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 2 .and. (rusage(i) .and. .not. rthin(i))) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ ndata=ndata+1
+ if(i > ndata)then
+ do k=1,nreal
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
+ end if
+ end do
+ end if
+ end if
+ if(luvob)then
+ nodata=nodata+2*ndata
+ else
+ nodata=nodata+nxdata
+ end if
+
! Write header record and data to output file for further processing
- allocate(cdata_out(nreal,ndata))
- do i=1,ndata
- do k=1,nreal
- cdata_out(k,i)=cdata_all(k,i)
- end do
- end do
- deallocate(cdata_all)
! deallocate(etabl)
- call count_obs(ndata,nreal,ilat,ilon,cdata_out,nobs)
+ call count_obs(ndata,nreal,ilat,ilon,cdata_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon
- write(lunout) cdata_out
- deallocate(cdata_out)
-900 continue
+ write(lunout) ((cdata_all(k,i),k=1,nreal),i=1,ndata)
+ deallocate(cdata_all,rusage,rthin)
+
if(diagnostic_reg .and. ntest>0) write(6,*)'READ_FL_HDOB: ',&
'ntest, disterrmax=', ntest,disterrmax
if(diagnostic_reg .and. nvtest>0) write(6,*)'READ_FL_HDOB: ',&
'nvtest,vdisterrmax=',ntest,vdisterrmax
if (ndata == 0) then
- write(6,*)'READ_FL_HDOB: no data to process'
+ write(6,*)'READ_FL_HDOB: no data to process',obstype
endif
- write(6,*)'READ_FL_HDOB: nreal=',nreal
+ write(6,*)'READ_FL_HDOB: nreal=',nreal,obstype
write(6,*)'READ_FL_HDOB: ntb,nread,ndata,nodata=',ntb,nread,ndata,nodata
diff --git a/src/gsi/read_gfs_ozone_for_regional.f90 b/src/gsi/read_gfs_ozone_for_regional.f90
index 5b6acce30b..52e07087c0 100644
--- a/src/gsi/read_gfs_ozone_for_regional.f90
+++ b/src/gsi/read_gfs_ozone_for_regional.f90
@@ -291,8 +291,8 @@ subroutine read_gfs_ozone_for_regional
if (nframe /= 0) call error_msg(trim(my_name),trim(filename),'nframe', &
'getfilehead',istop,nframe)
- fhour = float(nfhour) + float(nfminute)/r60 + &
- float(nfsecondn)/float(nfsecondd)/r3600
+ fhour = real(nfhour,r_kind) + real(nfminute,r_kind)/r60 + &
+ real(nfsecondn,r_kind)/real(nfsecondd,r_kind)/r3600
nsig_gfs=levs
jcap_org=njcap
@@ -319,9 +319,6 @@ subroutine read_gfs_ozone_for_regional
call stop2(85)
endif
- allocate(vcoord(levs+1,nvcoord))
- vcoord(:,1:nvcoord) = nems_vcoord(:,1:nvcoord,1)
- deallocate(nems_vcoord)
call nemsio_close(gfile,iret=iret)
if ( iret /= 0 ) call error_msg(trim(my_name),trim(filename),' ', &
@@ -416,7 +413,7 @@ subroutine read_gfs_ozone_for_regional
write(6,*)'READ_GFS_OZONE_FOR_REGIONAL: ***ERROR*** INVALID value for nvcoord=',sighead%nvcoord,filename
call stop2(85)
endif
- else if ( use_gfs_ncio ) then
+ else if ( use_gfs_ncio ) then
if (gfshead%nvcoord == 1) then
do k=1,nsig_gfs+1
bk5(k) = gfsheadv%vcoord(k,1)
@@ -437,6 +434,8 @@ subroutine read_gfs_ozone_for_regional
call stop2(85)
endif
else
+ allocate(vcoord(levs+1,nvcoord))
+ vcoord(:,1:nvcoord) = nems_vcoord(:,1:nvcoord,1)
if (nvcoord == 1) then
do k=1,nsig_gfs+1
bk5(k) = vcoord(k,1)
@@ -456,6 +455,7 @@ subroutine read_gfs_ozone_for_regional
write(6,*)'GET_GEFS_FOR_REGIONAL: ***ERROR*** INVALID value for nvcoord=',nvcoord
call stop2(85)
endif
+ deallocate(vcoord,nems_vcoord)
end if
! Load reference temperature array (used by general coordinate)
@@ -497,7 +497,6 @@ subroutine read_gfs_ozone_for_regional
vector=.false.
call general_sub2grid_create_info(grd_gfs,inner_vars,nlat_gfs,nlon_gfs,nsig_gfs,num_fields, &
.not.regional,vector)
- deallocate(vector)
jcap_gfs_test=jcap_gfs
call general_init_spec_vars(sp_gfs,jcap_gfs,jcap_gfs_test,grd_gfs%nlat,grd_gfs%nlon)
if (hires .and. .not. use_gfs_nemsio .and. .not. use_gfs_ncio) then
@@ -507,9 +506,6 @@ subroutine read_gfs_ozone_for_regional
! also want to set up regional grid structure variable grd_mix, which still has number of
! vertical levels set to nsig_gfs, but horizontal dimensions set to regional domain.
- num_fields=2*nsig_gfs
- allocate(vector(num_fields))
- vector=.false.
call general_sub2grid_create_info(grd_mix,inner_vars,nlat,nlon,nsig_gfs,num_fields,regional,vector)
deallocate(vector)
diff --git a/src/gsi/read_gmi.f90 b/src/gsi/read_gmi.f90
index 0f45aa7e28..6ad4d829a3 100644
--- a/src/gsi/read_gmi.f90
+++ b/src/gsi/read_gmi.f90
@@ -184,7 +184,7 @@ subroutine read_gmi(mype,val_gmi,ithin,rmesh,jsatid,gstime,&
integer(i_kind) :: jc,bufsat,n
integer(i_kind),dimension(5):: iobsdate
integer(i_kind):: method,iobs,num_obs
- integer(i_kind),parameter :: maxobs=4000000
+ integer(i_kind),parameter :: maxobs=6000000
!-- integer(i_kind),parameter :: nscan=74 ! after binning ifov, 221/3 + 1
integer(i_kind),parameter :: nscan=221
@@ -414,7 +414,7 @@ subroutine read_gmi(mype,val_gmi,ithin,rmesh,jsatid,gstime,&
call ufbrep(lnbufr,var_check1,1,nchanl,iret,'GMICHQ')
!call ufbrep(lnbufr,gmirfi,1,nchanl,iret,'GMIRFI')
call ufbrep(lnbufr,pixelsaza,1,ngs,iret,'SAZA')
- call ufbrep(lnbufr,val_angls,n_angls,ngs,iret,'SAMA SZA SMA SGA')
+ call ufbrep(lnbufr,val_angls,n_angls,ngs,iret,'BEARAZ SOZA SOLAZI SSGA')
call ufbint(lnbufr,pixelloc,2, 1,iret,'CLATH CLONH')
if (any(var_check1 < 99999999999_r_double)) then ! 100000000000 seems to be the missing value
@@ -528,6 +528,7 @@ subroutine read_gmi(mype,val_gmi,ithin,rmesh,jsatid,gstime,&
flgch = 0
iobs=iobs+1
+ if(iobs>maxobs) exit
end do read_loop
end do read_subset
690 continue
@@ -677,7 +678,7 @@ subroutine read_gmi(mype,val_gmi,ithin,rmesh,jsatid,gstime,&
if(.not. regional .and. dist1 > 0.75_r_kind) cycle obsloop
endif
- crit1 = crit1 + 10._r_kind * float(iskip)
+ crit1 = crit1 + 10._r_kind * real(iskip,r_kind)
call checkob(dist1,crit1,itx,iuse)
if(.not. iuse) then
cycle obsloop
@@ -695,7 +696,7 @@ subroutine read_gmi(mype,val_gmi,ithin,rmesh,jsatid,gstime,&
call deter_sfc(dlat,dlon,dlat_earth,dlon_earth,t4dv,isflg,idomsfc,sfcpct, &
ts,tsavg,vty,vfr,sty,stp,sm,sn,zz,ff10,sfcr)
- call deter_sfc_gmi(dlat_earth,dlon_earth,isflg,sfcpct)
+ call deter_sfc_gmi(dlat_earth,dlon_earth,isflg)
! Only keep obs over ocean - ej
@@ -818,7 +819,7 @@ subroutine read_gmi(mype,val_gmi,ithin,rmesh,jsatid,gstime,&
if(pos_max==0) then
j2=1
else
- j2=nint(float(pos_statis(i))/pos_max)
+ j2=nint(real(pos_statis(i),r_kind)/pos_max)
j2=max(1,j2)
endif
do j=1,pos_statis(i),j2
@@ -834,7 +835,7 @@ subroutine read_gmi(mype,val_gmi,ithin,rmesh,jsatid,gstime,&
if(pos_max==0) then
j2=1
else
- j2=nint(float(pos_statis(i))/pos_max)
+ j2=nint(real(pos_statis(i),r_kind)/pos_max)
j2=max(1,j2)
endif
do j=1,pos_statis(i),j2
diff --git a/src/gsi/read_goesglm.f90 b/src/gsi/read_goesglm.f90
index e0124abbf2..8746fa27dd 100644
--- a/src/gsi/read_goesglm.f90
+++ b/src/gsi/read_goesglm.f90
@@ -76,9 +76,8 @@ subroutine read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twindin,sis)
character(8) subset
character(1) sidchr(8)
- integer(i_kind) ireadmg,ireadsb,icntpnt,icount
+ integer(i_kind) ireadmg,ireadsb,icntpnt
integer(i_kind) lunin,i
- integer(i_kind) itx
integer(i_kind) ihh,idd,idate,iret,im,iy,k
integer(i_kind) nchanl,nreal,ilat,ilon
integer(i_kind) lqm
@@ -89,7 +88,6 @@ subroutine read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twindin,sis)
integer(i_kind) nmsg ! message index
integer(i_kind),parameter :: maxobs=2000000
integer(i_kind),dimension(5):: idate5
- integer(i_kind),allocatable,dimension(:):: isort,iloc
real(r_kind) time
real(r_kind) usage
@@ -99,7 +97,7 @@ subroutine read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twindin,sis)
real(r_kind) cdist,disterr,disterrmax,rlon00,rlat00
real(r_kind) vdisterrmax
real(r_kind) timex,timeobs,toff,t4dv,zeps
- real(r_kind),allocatable,dimension(:,:):: cdata_all,cdata_out
+ real(r_kind),allocatable,dimension(:,:):: cdata_all
!--- flash rate
real(r_kind),allocatable,dimension(:,:):: cdata_flash,cdata_flash_h
integer(i_kind) :: ndata_flash,ndata_flash_h
@@ -122,6 +120,10 @@ subroutine read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twindin,sis)
nreal=13
lob = obstype == 'goes_glm'
+ if(.not.lob) then
+ write(6,*) 'mix-up reading goes_glm ',obstype
+ return
+ end if
! . . . .
@@ -139,8 +141,7 @@ subroutine read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twindin,sis)
nmsg = 0
disterrmax=-9999.0_r_kind
- allocate(cdata_all(nreal,maxobs),isort(maxobs))
- isort = 0
+ allocate(cdata_all(nreal,maxobs))
cdata_all=zero
nread=0
ntest=0
@@ -224,7 +225,7 @@ subroutine read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twindin,sis)
call w3fs21(idate5,minan) ! analysis ref time in seconds relative to historic date
! Add obs reference time, then subtract analysis time to get obs time relative to analysis
- time_correction=float(minobs-minan)*r60inv
+ time_correction=real(minobs-minan,r_kind)*r60inv
else
time_correction=zero
end if
@@ -276,9 +277,9 @@ subroutine read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twindin,sis)
icntpnt=icntpnt+1
ndata=ndata+1
+ if(ndata>maxobs) exit
nodata=nodata+1
iout=ndata
- isort(icntpnt)=iout
if (ndata > maxobs) then
write(6,*)'READ_GOESGLM: ***WARNING*** ndata > maxobs for ',obstype
@@ -290,21 +291,19 @@ subroutine read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twindin,sis)
usage = zero
if (iuse_light(nlighttype) <= 0)usage=100._r_kind
- if (lob) then
- cdata_all(1,iout) =loe ! lightning observation error
- cdata_all(2,iout) =dlon ! grid relative longitude
- cdata_all(3,iout) =dlat ! grid relative latitude
- cdata_all(4,iout) =iout ! lightning obs
- cdata_all(5,iout) =rstation_id ! station id
- cdata_all(6,iout) =t4dv ! analysis time
- cdata_all(7,iout) =nlighttype ! type
- cdata_all(8,iout) =lmerr ! lightning max error
- cdata_all(9,iout) =lqm ! quality mark
- cdata_all(10,iout)=loe ! original lightning obs error loe
- cdata_all(11,iout)=usage ! usage parameter
- cdata_all(12,iout)=dlon_earth*rad2deg ! earth relative lon (degrees)
- cdata_all(13,iout)=dlat_earth*rad2deg ! earth relative lat (degrees)
- end if
+ cdata_all(1,iout) =loe ! lightning observation error
+ cdata_all(2,iout) =dlon ! grid relative longitude
+ cdata_all(3,iout) =dlat ! grid relative latitude
+ cdata_all(4,iout) =iout ! lightning obs
+ cdata_all(5,iout) =rstation_id ! station id
+ cdata_all(6,iout) =t4dv ! analysis time
+ cdata_all(7,iout) =nlighttype ! type
+ cdata_all(8,iout) =lmerr ! lightning max error
+ cdata_all(9,iout) =lqm ! quality mark
+ cdata_all(10,iout)=loe ! original lightning obs error loe
+ cdata_all(11,iout)=usage ! usage parameter
+ cdata_all(12,iout)=dlon_earth*rad2deg ! earth relative lon (degrees)
+ cdata_all(13,iout)=dlat_earth*rad2deg ! earth relative lat (degrees)
! end loop on read line BUFR
@@ -322,30 +321,7 @@ subroutine read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twindin,sis)
call closbf(lunin)
! Write header record and data to output file for further processing
- allocate(iloc(ndata))
- icount=0.
- do i=1,maxobs
- if(isort(i) > 0)then
- icount=icount+1
- iloc(icount)=isort(i)
- end if
- end do
- if(ndata /= icount)then
- write(6,*) ' READ_GOESGLM: mix up in read_goesglm ,ndata,icount ',ndata,icount
- call stop2(50)
- end if
- allocate(cdata_out(nreal,ndata))
- do i=1,ndata
- itx=iloc(i)
- do k=1,nreal
- cdata_out(k,i)=cdata_all(k,itx)
- end do
- end do
-
- deallocate(iloc,isort,cdata_all)
-
-! . . . .
! Call to the subroutine that transforms lightning strikes into lightning flash rate
@@ -360,9 +336,9 @@ subroutine read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twindin,sis)
allocate(cdata_flash_h(nreal,ndata_flash_h))
call convert_to_flash_rate &
- (nreal,ndata,cdata_out,ndata_flash_h,cdata_flash_h,ndata_flash)
+ (nreal,ndata,cdata_all,ndata_flash_h,cdata_flash_h,ndata_flash)
- deallocate(cdata_out)
+ deallocate(cdata_all)
ndata=ndata_flash
allocate(cdata_flash(nreal,ndata))
@@ -387,8 +363,8 @@ subroutine read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twindin,sis)
else ! ndata=0
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon
- write(lunout) cdata_out
- deallocate(cdata_out)
+ write(lunout) ((cdata_all(k,i),k=1,nreal),i=1,ndata)
+ deallocate(cdata_all)
end if !! if(ndata =/ 0) then
@@ -511,13 +487,13 @@ subroutine convert_to_flash_rate &
end do !! do iobs=2,ndata_strike
- darea=darea_sum/float(ndata_strike)
+ darea=darea_sum/real(ndata_strike,r_kind)
else !! ndata_strike=0
darea=zero
end if !! if(ndata_strike>0) then
- dtime=float(nhr_assimilation)
+ dtime=real(nhr_assimilation,r_kind)
! Regional
@@ -573,8 +549,8 @@ subroutine convert_to_flash_rate &
!! find lightning strikes near the (ii0,jj0) point
- xbound=float(ii0)
- ybound=float(jj0)
+ xbound=real(ii0,r_kind)
+ ybound=real(jj0,r_kind)
xflag=(xx>xbound) .AND. (xxybound) .AND. (yy0) then
- glon_central(index)=glon_central(index)/float(lcount(index))
- glat_central(index)=glat_central(index)/float(lcount(index))
- lon_central(index)= lon_central(index)/float(lcount(index))
- lat_central(index)= lat_central(index)/float(lcount(index))
+ glon_central(index)=glon_central(index)/real(lcount(index),r_kind)
+ glat_central(index)=glat_central(index)/real(lcount(index),r_kind)
+ lon_central(index)= lon_central(index)/real(lcount(index),r_kind)
+ lat_central(index)= lat_central(index)/real(lcount(index),r_kind)
endif !! if(lcount(index)>0) then
enddo !! do index=1,ngridh
@@ -652,7 +628,7 @@ subroutine convert_to_flash_rate &
cdata_flash_h( 3,icount)=glat_central(index)
if (darea>0._r_kind) then
- cdata_flash_h( 4,icount)=float(lcount(index))/(darea*dtime)
+ cdata_flash_h( 4,icount)=real(lcount(index),r_kind)/(darea*dtime)
else
cdata_flash_h( 4,icount)=0.
end if
@@ -726,22 +702,22 @@ subroutine convert_time (date_old,date_new,nmax)
jdd=INT(0.0001_r_kind*xdate(i))
idd=INT(xdate(i))-jdd*10000
- ysumidd=float(idd)
- dd=float(INT(0.01_r_kind*ysumidd))
+ ysumidd=real(idd,r_kind)
+ dd=real(INT(0.01_r_kind*ysumidd),r_kind)
hh=ysumidd-dd*100._r_kind
sumidd=sumidd+dd*24._r_kind+hh
enddo !! do i=1,nmax
- xsumidd=float(sumidd)/nmax
- ysumidd=float(INT(xsumidd))
+ xsumidd=real(sumidd,r_kind)/nmax
+ ysumidd=real(INT(xsumidd),r_kind)
kdd=INT(xsumidd/24._r_kind)
- xdd=float(kdd)
- xhh=ysumidd-float(kdd)*24._r_kind
+ xdd=real(kdd,r_kind)
+ xhh=ysumidd-real(kdd,r_kind)*24._r_kind
- ydate=float(jdd)*10000._r_kind+xdd*100._r_kind+xhh+xccyy
+ ydate=real(jdd,r_kind)*10000._r_kind+xdd*100._r_kind+xhh+xccyy
date_old=ydate
diff --git a/src/gsi/read_goesimgr_skycover.f90 b/src/gsi/read_goesimgr_skycover.f90
index dda9aad6f4..97eeb5e695 100644
--- a/src/gsi/read_goesimgr_skycover.f90
+++ b/src/gsi/read_goesimgr_skycover.f90
@@ -50,14 +50,14 @@ subroutine read_goesimgr_skycover(nread,ndata,nodata,infile,obstype,lunout,gsti
use constants, only: zero,one_tenth,one,deg2rad,half,&
three,four, r60inv,r10,r100,r2000
- use convinfo, only: nconvtype, &
- icuse,ictype,ioctype,&
- ithin_conv,rmesh_conv,pmesh_conv,ctwind
- use convthin, only: make3grids,map3grids,del3grids,use_all
+ use convinfo, only: nconvtype,icuse,ictype,ioctype,&
+ ithin_conv,rmesh_conv,pmesh_conv,ctwind,pmot_conv
+! use convinfo, only: icsubtype
+ use convthin, only: make3grids,map3grids_m,del3grids,use_all
use gridmod, only: regional,nlon,nlat,nsig,tll2xy,txy2ll,&
rlats,rlons
use deter_sfc_mod, only: deter_sfc2
- use obsmod, only: bmiss,ran01dom
+ use obsmod, only: bmiss,ran01dom,reduce_diag
use gsi_4dvar, only: l4dvar,l4densvar,iwinbgn,winlen,time_4dvar,thin4d
use adjust_cloudobs_mod, only: adjust_goescldobs
use mpimod, only: npe
@@ -95,9 +95,8 @@ subroutine read_goesimgr_skycover(nread,ndata,nodata,infile,obstype,lunout,gsti
integer(i_kind) :: iret,kx,pflag,nlevp,nmind,levs,idomsfc
integer(i_kind) :: low_cldamt_qc,mid_cldamt_qc,hig_cldamt_qc,tcamt_qc
integer(i_kind) :: ithin,klat1,klon1,klonp1,klatp1,kk,k,ilat,ilon,nchanl
- integer(i_kind) :: iout,ntmp,iiout,maxobs,icount,itx,iuse,idate,ierr
+ integer(i_kind) :: iout,maxobs,iuse,idate,ierr
integer(i_kind),dimension(5) :: idate5
- integer(i_kind),allocatable,dimension(:):: isort,iloc
real(r_kind) :: dlat,dlon,dlat_earth,dlon_earth,toff,t4dv
real(r_kind) :: dlat_earth_deg,dlon_earth_deg
real(r_kind) :: dx,dx1,dy,dy1,w00,w10,w01,w11,crit1,timedif,tdiff
@@ -106,10 +105,13 @@ subroutine read_goesimgr_skycover(nread,ndata,nodata,infile,obstype,lunout,gsti
real(r_kind) :: low_cldamt,mid_cldamt,hig_cldamt,usage,zz,sfcr,rstation_id
real(r_kind),allocatable,dimension(:):: presl_thin
real(r_kind),dimension(nsig):: presl
- real(r_kind),allocatable,dimension(:,:):: cdata_all,cdata_out
+ real(r_kind),allocatable,dimension(:,:):: cdata_all
real(r_double),dimension(9):: hdr
real(r_double),dimension(3):: goescld
-
+ logical,allocatable,dimension(:)::rthin,rusage
+ logical save_all
+! integer(i_kind) numthin,numqc,numrem,numall
+ integer(i_kind) nxdata,pmot
logical :: outside,ithinp,luse
@@ -196,8 +198,7 @@ subroutine read_goesimgr_skycover(nread,ndata,nodata,infile,obstype,lunout,gsti
end do
maxobs=ntb
- allocate(cdata_all(nreal,maxobs),isort(maxobs))
- isort = 0
+ allocate(cdata_all(nreal,maxobs),rusage(maxobs),rthin(maxobs))
cdata_all=zero
nread=0
nchanl=0
@@ -211,211 +212,240 @@ subroutine read_goesimgr_skycover(nread,ndata,nodata,infile,obstype,lunout,gsti
call openbf(lunin,'IN',lunin)
call datelen(10)
- loop_msg: do while (ireadmg(lunin,subset,idate) == 0)
- loop_readsb: do while (ireadsb(lunin) == 0)
- ntb=ntb+1
- ! - Extract type, date, and location information
- call ufbint(lunin,hdr,9,1,iret,hdrstr)
-
- ! - Compare relative obs time with window. If obs
- ! - falls outside of window, don't use this obs
- idate5(1) = hdr(2) ! year
- idate5(2) = hdr(3) ! month
- idate5(3) = hdr(4) ! day
- idate5(4) = hdr(5) ! hours
- idate5(5) = hdr(6) ! minutes
- call w3fs21(idate5,nmind)
- rminobs=real(nmind,8)+(real(hdr(7),8)*r60inv)!convert the seconds of the ob to minutes and store to rminobs
- t4dv = (rminobs-real(iwinbgn,r_kind))*r60inv
- tdiff=(rminobs-gstime)*r60inv !GS time is the analysis time in minutes from w3fs21
-
- if (l4dvar.or.l4densvar) then
- if (t4dvwinlen) cycle loop_readsb
- else
- ! - Check to make sure ob is within convinfo time window (ctwind) and
- ! - is within overwall time window twind (usually +-3)
- if( (abs(tdiff) > ctwind(nc)) .or. (abs(tdiff) > twind) )cycle loop_readsb
- endif
-
-
- kx=999_i_kind !hardwire typ to 999
- if(abs(hdr(8))>r90 .or. abs(hdr(9))>r360) cycle loop_readsb
- if(hdr(9)== r360)hdr(9)=hdr(9)-r360
- if(hdr(9) < zero)hdr(9)=hdr(9)+r360
- dlon_earth_deg = hdr(9)
- dlat_earth_deg = hdr(8)
- dlon_earth=hdr(9)*deg2rad
- dlat_earth=hdr(8)*deg2rad
- nread=nread+1
- if(regional)then
- call tll2xy(dlon_earth,dlat_earth,dlon,dlat,outside) ! convert to rotated coordinate
- if(outside) cycle loop_readsb ! check to see if outside regional domain
- else
- dlat = dlat_earth
- dlon = dlon_earth
- call grdcrd1(dlat,rlats,nlat,1)
- call grdcrd1(dlon,rlons,nlon,1)
- endif
+ pmot=nint(pmot_conv(nc))
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
+ rusage = .true.
+ rthin = .false.
+ use_all=.true.
+
+ loop_msg: do while (ireadmg(lunin,subset,idate) == 0)
+ loop_readsb: do while (ireadsb(lunin) == 0)
+ ntb=ntb+1
+ ! - Extract type, date, and location information
+ call ufbint(lunin,hdr,9,1,iret,hdrstr)
+
+ ! - Compare relative obs time with window. If obs
+ ! - falls outside of window, don't use this obs
+ idate5(1) = hdr(2) ! year
+ idate5(2) = hdr(3) ! month
+ idate5(3) = hdr(4) ! day
+ idate5(4) = hdr(5) ! hours
+ idate5(5) = hdr(6) ! minutes
+ call w3fs21(idate5,nmind)
+ rminobs=real(nmind,8)+(real(hdr(7),8)*r60inv)!convert the seconds of the ob to minutes and store to rminobs
+ t4dv = (rminobs-real(iwinbgn,r_kind))*r60inv
+ tdiff=(rminobs-gstime)*r60inv !GS time is the analysis time in minutes from w3fs21
+
+ if (l4dvar.or.l4densvar) then
+ if (t4dvwinlen) cycle loop_readsb
+ else
+ ! - Check to make sure ob is within convinfo time window (ctwind) and
+ ! - is within overwall time window twind (usually +-3)
+ if( (abs(tdiff) > ctwind(nc)) .or. (abs(tdiff) > twind) )cycle loop_readsb
+ endif
- ! Read in the obs
- goescld=bmiss
- call ufbint(lunin,goescld,3,1,levs,goescldstr_new)
- if (goescld(3) > r0_01_bmiss) then
+
+ kx=999_i_kind !hardwire typ to 999
+ if(abs(hdr(8))>r90 .or. abs(hdr(9))>r360) cycle loop_readsb
+ if(hdr(9)== r360)hdr(9)=hdr(9)-r360
+ if(hdr(9) < zero)hdr(9)=hdr(9)+r360
+ dlon_earth_deg = hdr(9)
+ dlat_earth_deg = hdr(8)
+ dlon_earth=hdr(9)*deg2rad
+ dlat_earth=hdr(8)*deg2rad
+ nread=nread+1
+ if(regional)then
+ call tll2xy(dlon_earth,dlat_earth,dlon,dlat,outside) ! convert to rotated coordinate
+ if(outside) cycle loop_readsb ! check to see if outside regional domain
+ else
+ dlat = dlat_earth
+ dlon = dlon_earth
+ call grdcrd1(dlat,rlats,nlat,1)
+ call grdcrd1(dlon,rlons,nlon,1)
+ endif
+
+ ! Read in the obs
+ goescld=bmiss
+ call ufbint(lunin,goescld,3,1,levs,goescldstr_new)
+ if (goescld(3) > r0_01_bmiss) then
! if ob is missing, look for it in old BUFR mnemonic sequence
- goescld=bmiss
- call ufbint(lunin,goescld,3,1,levs,goescldstr)
- if (goescld(3) > r0_01_bmiss) cycle loop_readsb !If obs are missing, cycle
- endif
- c_prvstg=cspval
- c_sprvstg=cspval
-
- ! - Set station ID
- rstation_id=goescld(1)
+ goescld=bmiss
+ call ufbint(lunin,goescld,3,1,levs,goescldstr)
+ if (goescld(3) > r0_01_bmiss) cycle loop_readsb !If obs are missing, cycle
+ endif
+ c_prvstg=cspval
+ c_sprvstg=cspval
+
+ ! - Set station ID
+ rstation_id=goescld(1)
- ithin=ithin_conv(nc)
- ithinp = ithin > 0 .and. pflag /= 0
-
- ! - Thin in vertical - note we can only thin in the horizontal
- ! - since sky cover is a 2D field. So this branch should never run
- ! - unless we get info about the vertical location of the clouds in the
- ! - future. Leaving here as a 'just-in-case' measure.
- if(ithinp )then
-! Interpolate guess pressure profile to observation location
- klon1= int(dlon); klat1= int(dlat)
- dx = dlon-klon1; dy = dlat-klat1
- dx1 = one-dx; dy1 = one-dy
- w00=dx1*dy1; w10=dx1*dy; w01=dx*dy1; w11=dx*dy
-
- klat1=min(max(1,klat1),nlat); klon1=min(max(0,klon1),nlon)
- if (klon1==0) klon1=nlon
- klatp1=min(nlat,klat1+1); klonp1=klon1+1
- if (klonp1==nlon+1) klonp1=1
+ ithin=ithin_conv(nc)
+ ithinp = ithin > 0 .and. pflag /= 0
+
+ ! - Thin in vertical - note we can only thin in the horizontal
+ ! - since sky cover is a 2D field. So this branch should never run
+ ! - unless we get info about the vertical location of the clouds in the
+ ! - future. Leaving here as a 'just-in-case' measure.
+ if(ithinp )then
+! Interpolate guess pressure profile to observation location
+ klon1= int(dlon); klat1= int(dlat)
+ dx = dlon-klon1; dy = dlat-klat1
+ dx1 = one-dx; dy1 = one-dy
+ w00=dx1*dy1; w10=dx1*dy; w01=dx*dy1; w11=dx*dy
+
+ klat1=min(max(1,klat1),nlat); klon1=min(max(0,klon1),nlon)
+ if (klon1==0) klon1=nlon
+ klatp1=min(nlat,klat1+1); klonp1=klon1+1
+ if (klonp1==nlon+1) klonp1=1
+ do kk=1,nsig
+ presl(kk)=w00*prsl_full(klat1 ,klon1 ,kk) + &
+ w10*prsl_full(klatp1,klon1 ,kk) + &
+ w01*prsl_full(klat1 ,klonp1,kk) + &
+ w11*prsl_full(klatp1,klonp1,kk)
+ end do
+ end if
+
+ iuse=icuse(nc)
+
+ ! General block for data thinning - if requested
+ if (ithin > 0 .and. iuse >=0) then
+ ! - Set data quality index for thinning
+ if (thin4d) then
+ timedif = zero
+ else
+ timedif=abs(t4dv-toff)
+ endif
+
+ crit1 = timedif/r6+half
+
+ ! - simple 1-to-1 mapping of vertical levels when no thinning in the vertical
+ if (pflag==0) then
do kk=1,nsig
- presl(kk)=w00*prsl_full(klat1 ,klon1 ,kk) + &
- w10*prsl_full(klatp1,klon1 ,kk) + &
- w01*prsl_full(klat1 ,klonp1,kk) + &
- w11*prsl_full(klatp1,klonp1,kk)
+ presl_thin(kk)=presl(kk)
end do
- end if
-
- iuse=icuse(nc)
-
- ! General block for data thinning - if requested
- if (ithin > 0 .and. iuse >=0) then
- ntmp=ndata ! counting moved to map3gridS
- ! - Set data quality index for thinning
- if (thin4d) then
- timedif = zero
- else
- timedif=abs(t4dv-toff)
- endif
-
- crit1 = timedif/r6+half
-
- ! - simple 1-to-1 mapping of vertical levels when no thinning in the vertical
- if (pflag==0) then
- do kk=1,nsig
- presl_thin(kk)=presl(kk)
- end do
- endif
- ppb=one_tenth*1013.25_r_kind !number is irrelevant for 2D - set to standard SLP -> 1013.25 and convert from mb to cb
- call map3grids(-1,pflag,presl_thin,nlevp,dlat_earth,dlon_earth,&
- ppb,crit1,ndata,iout,ntb,iiout,luse,.false.,.false.)
-
- if (.not. luse) cycle loop_readsb
- if(iiout > 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+1
- endif
- isort(ntb)=iout
- else ! - no thinnning
- ndata=ndata+1
- nodata=nodata+1
- iout=ndata
- isort(ntb)=iout
- endif
-
- !- Set usage variable
- usage = 0
- if(iuse <= 0)usage=r100
-
- ! Get information from surface file necessary for conventional data here
- call deter_sfc2(dlat_earth,dlon_earth,t4dv,idomsfc,tsavg,ff10,sfcr,zz)
-
- ! - Obtain the ob and tune the QC marks for ob error tuning a bit later
-
- call adjust_goescldobs(goescld(3),tdiff,dlat_earth,dlon_earth, &
- low_cldamt,low_cldamt_qc,mid_cldamt,mid_cldamt_qc, &
- hig_cldamt,hig_cldamt_qc,tcamt,tcamt_qc)
-
-
- if(tcamt_qc==15 .or. tcamt_qc==12 .or. tcamt_qc==9 .or. tcamt_qc==8) usage=r100
- tcamt_oe=20.0_r_kind
- if(tcamt_qc==1) tcamt_oe=tcamt_oe*1.25_r_kind
- if(tcamt_qc==2) tcamt_oe=tcamt_oe*1.50_r_kind
- if(tcamt_qc==3) tcamt_oe=tcamt_oe*1.75_r_kind
-
- cdata_all( 1,iout)=tcamt_oe ! obs error
- cdata_all( 2,iout)=dlon ! grid relative longitude
- cdata_all( 3,iout)=dlat ! grid relative latitude
- cdata_all( 4,iout)=tcamt ! total cloud amount (%)
- cdata_all( 5,iout)=rstation_id ! station ID
- cdata_all( 6,iout)=t4dv ! time
- cdata_all( 7,iout)=nc ! type
- cdata_all( 8,iout)=tcamt_qc ! quality mark
- cdata_all( 9,iout)=usage ! usage parameter
- cdata_all(10,iout)=idomsfc ! dominate surface type
- cdata_all(11,iout)=tsavg ! skin temperature
- cdata_all(12,iout)=ff10 ! 10 meter wind factor
- cdata_all(13,iout)=sfcr ! surface roughness
- cdata_all(14,iout)=dlon_earth_deg ! earth relative longitude (degrees)
- cdata_all(15,iout)=dlat_earth_deg ! earth relative latitude (degrees)
- cdata_all(16,iout)=bmiss ! station elevation (m)
- cdata_all(17,iout)=bmiss ! observation height (m)
- cdata_all(18,iout)=zz ! terrain height at ob location
- cdata_all(19,iout)=r_prvstg(1,1) ! provider name
- cdata_all(20,iout)=r_sprvstg(1,1) ! subprovider name
-
- enddo loop_readsb
-
- enddo loop_msg
-
-! Close unit to bufr file
- call closbf(lunin)
-! Deallocate arrays used for thinning data
- if (.not.use_all) then
- deallocate(presl_thin)
- call del3grids
- endif
+ endif
+ ppb=one_tenth*1013.25_r_kind !number is irrelevant for 2D - set to standard SLP -> 1013.25 and convert from mb to cb
+ call map3grids_m(-1,save_all,pflag,presl_thin,nlevp, &
+ dlat_earth,dlon_earth,ppb,crit1,ndata,&
+ luse,maxobs,rthin,.false.,.false.)
+
+ if (.not. luse) cycle loop_readsb
+ else ! - no thinnning
+ ndata=ndata+1
+ endif
+ iout=ndata
+
+ !- Set usage variable
+ usage = 0
+ if(iuse <= 0)usage=r100
+
+ ! Get information from surface file necessary for conventional data here
+ call deter_sfc2(dlat_earth,dlon_earth,t4dv,idomsfc,tsavg,ff10,sfcr,zz)
+
+ ! - Obtain the ob and tune the QC marks for ob error tuning a bit later
+
+ call adjust_goescldobs(goescld(3),tdiff,dlat_earth,dlon_earth, &
+ low_cldamt,low_cldamt_qc,mid_cldamt,mid_cldamt_qc, &
+ hig_cldamt,hig_cldamt_qc,tcamt,tcamt_qc)
+
+
+ if(tcamt_qc==15 .or. tcamt_qc==12 .or. tcamt_qc==9 .or. tcamt_qc==8) usage=r100
+ tcamt_oe=20.0_r_kind
+ if(tcamt_qc==1) tcamt_oe=tcamt_oe*1.25_r_kind
+ if(tcamt_qc==2) tcamt_oe=tcamt_oe*1.50_r_kind
+ if(tcamt_qc==3) tcamt_oe=tcamt_oe*1.75_r_kind
+
+ cdata_all( 1,iout)=tcamt_oe ! obs error
+ cdata_all( 2,iout)=dlon ! grid relative longitude
+ cdata_all( 3,iout)=dlat ! grid relative latitude
+ cdata_all( 4,iout)=tcamt ! total cloud amount (%)
+ cdata_all( 5,iout)=rstation_id ! station ID
+ cdata_all( 6,iout)=t4dv ! time
+ cdata_all( 7,iout)=nc ! type
+ cdata_all( 8,iout)=tcamt_qc ! quality mark
+ cdata_all( 9,iout)=usage ! usage parameter
+ cdata_all(10,iout)=idomsfc ! dominate surface type
+ cdata_all(11,iout)=tsavg ! skin temperature
+ cdata_all(12,iout)=ff10 ! 10 meter wind factor
+ cdata_all(13,iout)=sfcr ! surface roughness
+ cdata_all(14,iout)=dlon_earth_deg ! earth relative longitude (degrees)
+ cdata_all(15,iout)=dlat_earth_deg ! earth relative latitude (degrees)
+ cdata_all(16,iout)=bmiss ! station elevation (m)
+ cdata_all(17,iout)=bmiss ! observation height (m)
+ cdata_all(18,iout)=zz ! terrain height at ob location
+ cdata_all(19,iout)=r_prvstg(1,1) ! provider name
+ cdata_all(20,iout)=r_sprvstg(1,1) ! subprovider name
+ if(usage >=r100)rusage(ndata)=.false.
+
+ enddo loop_readsb
+
+ enddo loop_msg
+
+! Close unit to bufr file
+ call closbf(lunin)
+! Deallocate arrays used for thinning data
+ if (.not.use_all) then
+ deallocate(presl_thin)
+ call del3grids
+ endif
! Normal exit
-
-! Write header record and data to output file for further processing
- allocate(iloc(ndata))
- icount=0
- do i=1,maxobs
- if(isort(i) > 0)then
- icount=icount+1
- iloc(icount)=isort(i)
+ nxdata=ndata
+ ndata=0
+ if(nxdata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,nxdata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' sky ',trim(ioctype(nc)),ictype(nc),icsubtype(nc),numall,numrem,numqc,numthin
+! If thinned data set usage
+ if (ithin > 0 .and. ithin <5) then
+ do i=1,nxdata
+ if(rthin(i))then
+ cdata_all(9,i)=100._r_kind
+ cdata_all(8,i)=14
+ end if
+ end do
end if
- end do
- if(ndata /= icount)then
- write(6,*) myname,': ndata and icount do not match STOPPING...ndata,icount ',ndata,icount
- call stop2(50)
+! If flag to not save thinned data is set - compress data
+ if(pmot /= 1)then
+ do i=1,nxdata
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 2 .and. (rusage(i) .and. .not. rthin(i))) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ ndata=ndata+1
+ if(i > ndata)then
+ do k=1,nreal
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
+ end if
+ end do
+ end if
+ nodata=nodata+ndata
end if
- allocate(cdata_out(nreal,ndata))
- do i=1,ndata
- itx=iloc(i)
- do k=1,nreal
- cdata_out(k,i)=cdata_all(k,itx)
- end do
- end do
- deallocate(iloc,isort,cdata_all)
+
+! Write header record and data to output file for further processing
- call count_obs(ndata,nreal,ilat,ilon,cdata_out,nobs)
+ call count_obs(ndata,nreal,ilat,ilon,cdata_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon,ndata
- write(lunout) cdata_out
+ write(lunout) ((cdata_all(k,i),k=1,nreal),i=1,ndata)
- deallocate(cdata_out)
+ deallocate(cdata_all,rusage,rthin)
if (ndata == 0) then
write(6,*)myname,'no read_goesimgr_skycover data'
diff --git a/src/gsi/read_goesndr.f90 b/src/gsi/read_goesndr.f90
index 86fc1f0a5c..7c55b6ab4c 100644
--- a/src/gsi/read_goesndr.f90
+++ b/src/gsi/read_goesndr.f90
@@ -382,7 +382,7 @@ subroutine read_goesndr(mype,val_goes,ithin,rmesh,jsatid,infile,&
nread=nread+nchanl
crit0=0.01_r_kind
- if(ifov < mfov .and. ifov > 0) crit0 = crit0+two*float(mfov-ifov)
+ if(ifov < mfov .and. ifov > 0) crit0 = crit0+two*real(mfov-ifov,r_kind)
timeinflat=6.0_r_kind
call tdiff2crit(tdiff,ptime,ithin_time,timeinflat,crit0,crit1,it_mesh)
call map2tgrid(dlat_earth,dlon_earth,dist1,crit1,itx,ithin,itt,iuse,sis,it_mesh=it_mesh)
diff --git a/src/gsi/read_gps.f90 b/src/gsi/read_gps.f90
index 3d8379ee3b..02012cb5f6 100644
--- a/src/gsi/read_gps.f90
+++ b/src/gsi/read_gps.f90
@@ -137,21 +137,32 @@ subroutine read_gps(nread,ndata,nodata,infile,lunout,obstype,twind, &
bend_error,ref_error,bend_pccf,ref_pccf
real(r_kind),allocatable,dimension(:,:):: cdata_all
-
- integer(i_kind),parameter:: n1ahdr=10
+
+!> xuanli
+! integer(i_kind),parameter:: n1ahdr=10
+ integer(i_kind),parameter:: n1ahdr=13
+!< xuanli
real(r_double),dimension(n1ahdr):: bfr1ahdr
real(r_double),dimension(50,maxlevs):: data1b
real(r_double),dimension(50,maxlevs):: data2a
real(r_double),dimension(maxlevs):: nreps_this_ROSEQ2
+
+!> xuanli
+ real(r_kind):: azm_ang, sat_ascd, sat_constid, siid, ogce
+!< xuanli
data lnbufr/10/
- data hdr1a / 'YEAR MNTH DAYS HOUR MINU PCCF ELRC SAID PTID GEODU' /
+! data hdr1a / 'YEAR MNTH DAYS HOUR MINU PCCF ELRC SAID PTID GEODU' /
+ data hdr1a / 'YEAR MNTH DAYS HOUR MINU PCCF ELRC SAID PTID GEODU SCLF SIID OGCE' /
data nemo /'QFRO'/
!***********************************************************************************
maxobs=2e6
- nreal=maxinfo
+!> xuanli
+! nreal=maxinfo
+ nreal=24
+!< xuanli
nchanl=0
ilon=2
ilat=3
@@ -170,7 +181,6 @@ subroutine read_gps(nread,ndata,nodata,infile,lunout,obstype,twind, &
write(6,*)'READ GPS: CONVINFO DOES NOT INCLUDE ANY ',trim(sis),' DATA'
return
end if
-
! Open file for input, then read bufr data
open(lnbufr,file=trim(infile),form='unformatted')
call openbf(lnbufr,'IN',lnbufr)
@@ -214,16 +224,19 @@ subroutine read_gps(nread,ndata,nodata,infile,lunout,obstype,twind, &
call ufbint(lnbufr,qfro,1,1,iret,nemo)
! observation time in minutes
- idate5(1) = bfr1ahdr(1) ! year
- idate5(2) = bfr1ahdr(2) ! month
- idate5(3) = bfr1ahdr(3) ! day
- idate5(4) = bfr1ahdr(4) ! hour
- idate5(5) = bfr1ahdr(5) ! minute
- pcc=bfr1ahdr(6) ! profile per cent confidence
- roc=bfr1ahdr(7) ! Earth local radius of curvature
- said=bfr1ahdr(8) ! Satellite identifier
- ptid=bfr1ahdr(9) ! Platform transmitter ID number
- geoid=bfr1ahdr(10) ! Geoid undulation
+ idate5(1) = bfr1ahdr(1) ! year
+ idate5(2) = bfr1ahdr(2) ! month
+ idate5(3) = bfr1ahdr(3) ! day
+ idate5(4) = bfr1ahdr(4) ! hour
+ idate5(5) = bfr1ahdr(5) ! minute
+ pcc=bfr1ahdr(6) ! profile per cent confidence
+ roc=bfr1ahdr(7) ! Earth local radius of curvature
+ said=bfr1ahdr(8) ! Satellite identifier
+ ptid=bfr1ahdr(9) ! Platform transmitter ID number
+ geoid=bfr1ahdr(10) ! Geoid undulation
+ sat_constid=bfr1ahdr(11) ! Satellite classification
+ siid=bfr1ahdr(12) ! Satellite instrument
+ ogce = bfr1ahdr(13) ! Identification of originating/generating centre
call w3fs21(idate5,minobs)
! Locate satellite id in convinfo file
@@ -235,7 +248,7 @@ subroutine read_gps(nread,ndata,nodata,infile,lunout,obstype,twind, &
exit find_loop
endif
end do find_loop
- if (ikx==0) then
+ if (ikx==0) then
cycle read_loop
endif
@@ -296,6 +309,16 @@ subroutine read_gps(nread,ndata,nodata,infile,lunout,obstype,twind, &
endif
endif
+!> xuanli ascending flag: when qfro bit3 is set, occultation is ascending
+! bit3 is clear, occultation is descending
+ sat_ascd = 0.0
+ call upftbv(lnbufr,nemo,qfro,mxib,ibit,nib)
+ if(nib > 0) then
+ do i=1,nib
+ if(ibit(i) .eq. 3) sat_ascd=1.0
+ enddo
+ endif
+!< xuanli
! Read bending angle information
! Get the number of occurences of sequence ROSEQ2 in this subset
@@ -345,6 +368,7 @@ subroutine read_gps(nread,ndata,nodata,infile,lunout,obstype,twind, &
nread=nread+1 ! count observations
rlat=data1b(1,k) ! earth relative latitude (degrees)
rlon=data1b(2,k) ! earth relative longitude (degrees)
+ azm_ang=data1b(3,k) ! azimuth angle !xuanli
height=data2a(1,k)
ref=data2a(2,k)
ref_error=data2a(4,k)
@@ -368,8 +392,7 @@ subroutine read_gps(nread,ndata,nodata,infile,lunout,obstype,twind, &
good=.true.
if((abs(rlat)>90._r_kind).or.(abs(rlon)>r360).or.(height<=zero)) then
good=.false.
- endif
- if (ref_obs) then
+ else if (ref_obs) then
if ((ref>=1.e+9_r_kind).or.(ref<=zero).or.(height>=1.e+9_r_kind)) then
good=.false.
endif
@@ -440,7 +463,16 @@ subroutine read_gps(nread,ndata,nodata,infile,lunout,obstype,twind, &
cdata_all(14,ndata)= dlon_earth_deg ! earth relative longitude (degrees)
cdata_all(15,ndata)= dlat_earth_deg ! earth relative latitude (degrees)
cdata_all(16,ndata)= geoid ! geoid undulation (m)
-
+!> xuanli
+ cdata_all(17,ndata)= qfro ! qfro
+ cdata_all(18,ndata)= sat_ascd ! ascending flag
+ cdata_all(19,ndata)= azm_ang ! azimuth angle
+ cdata_all(20,ndata)= sat_constid ! satellite classification
+ cdata_all(21,ndata)= siid ! occulting satellite
+ cdata_all(22,ndata)= ogce ! Identification of originating/generating centre
+ cdata_all(23,ndata)= ref ! refractivity obs (units of N)
+ cdata_all(24,ndata)= height ! geometric height above geoid (m)
+!< xuanli
else
notgood = notgood + 1
end if
@@ -466,8 +498,9 @@ subroutine read_gps(nread,ndata,nodata,infile,lunout,obstype,twind, &
write(6,*)'READ_GPS: # bad or missing data=', notgood
do i=1,ngpsro_type
if (nmrecs_id(i)>0) &
- write(6,1020)'READ_GPS: LEO_id,nprof_gps = ',gpsro_itype(i),nmrecs_id(i)
+ write(6,1021)'READ_GPS: LEO_id,nprof_gps = ',gpsro_itype(i),nmrecs_id(i)
end do
+1021 format(a31,i6,i6)
write(6,1020)'READ_GPS: ref_obs,nprof_gps= ',ref_obs,nprof_gps
1020 format(a31,L,i6)
diff --git a/src/gsi/read_iasi.f90 b/src/gsi/read_iasi.f90
index 367c224508..362d7257a4 100644
--- a/src/gsi/read_iasi.f90
+++ b/src/gsi/read_iasi.f90
@@ -118,7 +118,7 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
use crtm_spccoeff, only: sc,crtm_spccoeff_load,crtm_spccoeff_destroy
use gridmod, only: diagnostic_reg,regional,nlat,nlon,&
tll2xy,txy2ll,rlats,rlons
- use constants, only: zero,deg2rad,rad2deg,r60inv,one,ten,r100
+ use constants, only: zero,deg2rad,rad2deg,r60inv,one,ten,r100,r_missing
use gsi_4dvar, only: l4dvar,l4densvar,iwinbgn,winlen
use calc_fov_crosstrk, only: instrument_init, fov_check, fov_cleanup
use deter_sfc_mod, only: deter_sfc,deter_sfc_fov
@@ -127,6 +127,7 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
use gsi_nstcouplermod, only: gsi_nstcoupler_skindepth, gsi_nstcoupler_deter
use mpimod, only: npe
use gsi_io, only: verbose
+ use qcmod, only: iasi_cads
! use radiance_mod, only: rad_obs_type
implicit none
@@ -175,7 +176,6 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
character(len=4) :: senname
character(len=80) :: allspotlist
character(len=40) :: infile2
- integer(i_kind) :: jstart
integer(i_kind) :: iret,ireadsb,ireadmg,irec,next, nrec_startx
integer(i_kind),allocatable,dimension(:) :: nrec
@@ -202,17 +202,18 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
real(r_kind),dimension(0:3) :: ts
real(r_kind),dimension(10) :: sscale
real(crtm_kind),allocatable,dimension(:) :: temperature
+ real(r_kind),allocatable,dimension(:) :: scalef
real(r_kind),allocatable,dimension(:,:):: data_all
real(r_kind) cdist,disterr,disterrmax,dlon00,dlat00
logical :: outside,iuse,assim,valid
logical :: iasi,quiet,cloud_info
- integer(i_kind) :: ifov, instr, iscn, ioff, sensorindex
+ integer(i_kind) :: ifov, instr, iscn, ioff, sensorindex_iasi
integer(i_kind) :: i, j, l, iskip, ifovn, bad_line, ksatid, kidsat, llll
integer(i_kind) :: nreal, isflg
integer(i_kind) :: itx, k, nele, itt, n
- integer(i_kind):: iexponent,maxinfo, bufr_nchan
+ integer(i_kind):: iexponent,maxinfo, bufr_nchan, dval_info
integer(i_kind):: idomsfc(1)
integer(i_kind):: ntest
integer(i_kind):: error_status, irecx,ierr
@@ -221,8 +222,18 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
integer(i_kind) :: sfc_channel_index
integer(i_kind),allocatable, dimension(:) :: channel_number, sc_index, bufr_index
integer(i_kind),allocatable, dimension(:) :: bufr_chan_test
- character(len=20),dimension(1):: sensorlist
-
+ character(len=20),allocatable, dimension(:):: sensorlist
+
+! Imager clouser information for CADS
+ integer(i_kind) :: sensorindex_imager, cads_info
+ integer(i_kind),dimension(7) :: imager_cluster_index
+ logical :: imager_coeff
+ logical,dimension(7) :: imager_cluster_flag
+ character(len=80) :: spc_filename
+ real(r_kind),dimension(33,7) :: imager_info
+ real(r_kind),dimension(7) :: imager_cluster_size
+ real(r_kind),dimension(2) :: imager_mean, imager_std_dev
+ real(r_kind) :: imager_cluster_tot
! Set standard parameters
character(8),parameter:: fov_flag="crosstrk"
@@ -238,7 +249,7 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
integer(i_kind),parameter :: ilon = 3
integer(i_kind),parameter :: ilat = 4
real(r_kind) :: ptime,timeinflat,crit0
- integer(i_kind) :: ithin_time,n_tbin,it_mesh
+ integer(i_kind) :: ithin_time,n_tbin,it_mesh,jstart
logical print_verbose
print_verbose=.false.
@@ -248,8 +259,11 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
maxinfo = 31
disterrmax=zero
ntest=0
- if(dval_use) maxinfo=maxinfo+2
- nreal = maxinfo + nstinfo
+ dval_info = 0
+ if(dval_use) dval_info = 2
+ cads_info = 0
+ if(iasi_cads) cads_info = 23
+ nreal = maxinfo + cads_info + dval_info + nstinfo
ndata = 0
nodata = 0
@@ -315,7 +329,19 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
! load spectral coefficient structure
quiet=.not. verbose
- sensorlist(1)=sis
+
+ imager_coeff = .false.
+ spc_filename =trim(crtm_coeffs_path)//'avhrr3_'//trim(jsatid)//'.SpcCoeff.bin'
+ inquire(file=trim(spc_filename), exist=imager_coeff)
+ if ( imager_coeff ) then
+ allocate( sensorlist(2))
+ sensorlist(1) = sis
+ sensorlist(2) = 'avhrr3_'//trim(jsatid)
+ else
+ allocate( sensorlist(1))
+ sensorlist(1) = sis
+ endif
+
if( crtm_coeffs_path /= "" ) then
if(mype_sub==mype_root .and. print_verbose) write(6,*)'READ_IASI: crtm_spccoeff_load() on path "'//trim(crtm_coeffs_path)//'"'
error_status = crtm_spccoeff_load(sensorlist,&
@@ -330,6 +356,31 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
call stop2(71)
endif
+! find IASI sensorindex
+ sensorindex_iasi = 0
+ if ( sc(1)%sensor_id(1:4) == 'iasi' ) then
+ sensorindex_iasi = 1
+ else
+ write(6,*)'READ_IASI: ***ERROR*** sensorindex_iasi not set NO IASI DATA USED'
+ write(6,*)'READ_IASI: We are looking for ', sc(1)%sensor_id, ' TERMINATE PROGRAM EXECUTION'
+ call stop2(71)
+ end if
+
+! find imager sensorindex
+ sensorindex_imager = 0
+ if ( iasi_cads .and. imager_coeff ) then
+ if ( sc(2)%sensor_id(1:4) == 'avhr' ) then
+ sensorindex_imager = 2
+ imager_coeff = .true.
+ else
+ write(6,*)'READ_IASI: ***ERROR*** sensorindex_imager is not set NO IASI DATA USED'
+ write(6,*)'READ_IASI: We are looking for ', sc(2)%sensor_id
+ imager_coeff = .false.
+ end if
+ else
+ imager_coeff = .false.
+ end if
+
! Find the channels being used (from satinfo file) in the spectral coef. structure.
do i=subset_start,subset_end
channel_number(i -subset_start +1) = nuchan(i)
@@ -337,23 +388,13 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
sc_index(:) = 0
satinfo_chan: do i=1,satinfo_nchan
spec_coef: do l=1,sc(1)%n_channels
- if ( channel_number(i) == sc(1)%sensor_channel(l) ) then
+ if ( channel_number(i) == sc(sensorindex_iasi)%sensor_channel(l) ) then
sc_index(i) = l
exit spec_coef
endif
end do spec_coef
end do satinfo_chan
-! find IASI sensorindex
- sensorindex = 0
- if ( sc(1)%sensor_id(1:4) == 'iasi' ) then
- sensorindex = 1
- else
- write(6,*)'READ_IASI: sensorindex not set NO IASI DATA USED'
- write(6,*)'READ_IASI: We are looking for ', sc(1)%sensor_id, ' TERMINATE PROGRAM EXECUTION'
- call stop2(71)
- end if
-
! Calculate parameters needed for FOV-based surface calculation.
if (isfcalc==1)then
instr=18
@@ -396,6 +437,7 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
allocate(temperature(1)) ! dependent on # of channels in the bufr file
allocate(allchan(2,1)) ! actual values set after ireadsb
allocate(bufr_chan_test(1))! actual values set after ireadsb
+ allocate(scalef(1))
! Big loop to read data file
next=0
@@ -442,10 +484,11 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
bufr_size = size(temperature,1)
if ( bufr_size /= bufr_nchan ) then ! Re-allocation if number of channels has changed
! Allocate the arrays needed for the channel and radiance array
- deallocate(temperature,allchan,bufr_chan_test)
+ deallocate(temperature,allchan,bufr_chan_test,scalef)
allocate(temperature(bufr_nchan)) ! dependent on # of channels in the bufr file
allocate(allchan(2,bufr_nchan))
allocate(bufr_chan_test(bufr_nchan))
+ allocate(scalef(bufr_nchan))
bufr_chan_test(:)=0
endif ! allocation if
@@ -575,7 +618,7 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
nread = nread + satinfo_nchan
crit0 = 0.01_r_kind
- if( llll > 1 ) crit0 = crit0 + r100 * float(llll)
+ if( llll > 1 ) crit0 = crit0 + r100 * real(llll,r_kind)
timeinflat=6.0_r_kind
call tdiff2crit(tdiff,ptime,ithin_time,timeinflat,crit0,crit1,it_mesh)
call map2tgrid(dlat_earth,dlon_earth,dist1,crit1,itx,ithin,itt,iuse,sis,it_mesh=it_mesh)
@@ -596,7 +639,7 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
! Compare IASI satellite scan angle and zenith angle
piece = -step_adjust
if ( mod(ifovn,2) == 1) piece = step_adjust
- lza = ((start + float((ifov-1)/4)*step) + piece)*deg2rad
+ lza = ((start + real((ifov-1)/4,r_kind)*step) + piece)*deg2rad
sat_height_ratio = (earth_radius + linele(4))/earth_radius
lzaest = asin(sat_height_ratio*sin(lza))*rad2deg
if (abs(sat_zenang - lzaest) > one) then
@@ -647,6 +690,9 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
if (iret == 7 .and. cloud_frac(1) <= r100 .and. cloud_frac(1) >= zero) then
pred = r100 - cloud_frac(1)
cloud_info = .true.
+ cloud_frac = cloud_frac/r100
+ else
+ cloud_frac = r_missing
endif
crit1 = crit1 + pred
@@ -675,6 +721,18 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
! Read IASI channel number(CHNM) and radiance (SCRA)
call ufbseq(lnbufr,allchan,2,bufr_nchan,iret,'IASICHN')
+ jstart=1
+ scalef=one
+ do i=1,bufr_nchan
+ scaleloop: do j=jstart,10
+ if(allchan(1,i) >= cscale(1,j) .and. allchan(1,i) <= cscale(2,j))then
+ scalef(i) = sscale(j)
+ jstart=j
+ exit scaleloop
+ end if
+ end do scaleloop
+ end do
+
if (iret /= bufr_nchan) then
write(6,*)'READ_IASI: ### ERROR IN READING ', senname, ' BUFR DATA:', &
iret, ' CH DATA IS READ INSTEAD OF ',bufr_nchan
@@ -703,52 +761,47 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
cycle read_loop
endif
- iskip = 0
- jstart=1
+!$omp parallel do schedule(dynamic,1) private(i,sc_chan,bufr_chan,radiance)
channel_loop: do i=1,satinfo_nchan
- sc_chan = sc_index(i)
- if ( bufr_index(i) == 0 ) cycle channel_loop
bufr_chan = bufr_index(i)
+ if (bufr_chan > 0 ) then
! check that channel number is within reason
- if (( allchan(2,bufr_chan) > zero .and. allchan(2,bufr_chan) < 99999._r_kind)) then ! radiance bounds
- radiance = allchan(2,bufr_chan)
- scaleloop: do j=jstart,10
- if(allchan(1,bufr_chan) >= cscale(1,j) .and. allchan(1,bufr_chan) <= cscale(2,j))then
- radiance = allchan(2,bufr_chan)*sscale(j)
- jstart=j
- exit scaleloop
- end if
- end do scaleloop
- call crtm_planck_temperature(sensorindex,sc_chan,radiance,temperature(bufr_chan))
- else
- temperature(bufr_chan) = tbmin
- endif
+ if (( allchan(2,bufr_chan) > zero .and. allchan(2,bufr_chan) < 99999._r_kind)) then ! radiance bounds
+ radiance = allchan(2,bufr_chan)*scalef(bufr_chan)
+ sc_chan = sc_index(i)
+ call crtm_planck_temperature(sensorindex_iasi,sc_chan,radiance,temperature(bufr_chan))
+ else
+ temperature(bufr_chan) = tbmin
+ endif
+ end if
end do channel_loop
! Check for reasonable temperature values
+ iskip = 0
skip_loop: do i=1,satinfo_nchan
if ( bufr_index(i) == 0 ) cycle skip_loop
bufr_chan = bufr_index(i)
if(temperature(bufr_chan) <= tbmin .or. temperature(bufr_chan) > tbmax ) then
- temperature(bufr_chan) = min(tbmax,max(zero,temperature(bufr_chan)))
+ temperature(bufr_chan) = min(tbmax,max(tbmin,temperature(bufr_chan)))
if(iuse_rad(ioff+i) >= 0)iskip = iskip + 1
endif
end do skip_loop
- if(iskip > 0 .and. print_verbose)write(6,*) ' READ_IASI : iskip > 0 ',iskip
- if( iskip > 0 )cycle read_loop
+ if(iskip > 0)then
+ if(print_verbose)write(6,*) ' READ_IASI : iskip > 0 ',iskip
+ cycle read_loop
+ end if
- crit1=crit1 + ten*float(iskip)
+! crit1=crit1 + ten*real(iskip,r_kind)
-! If the surface channel exists (~960.0 cm-1) and the AVHRR cloud information is missing, use an
+! If the surface channel exists (~960.0 cm-1) and the imager cloud information is missing, use an
! estimate of the surface temperature to determine if the profile may be clear.
if (.not. cloud_info) then
pred = tsavg*0.98_r_kind - temperature(sfc_channel_index)
pred = max(pred,zero)
+ crit1=crit1 + pred
endif
- crit1=crit1 + pred
-
! Map obs to grids
if (pred == zero) then
call finalcheck(dist1,crit1,itx,iuse)
@@ -757,6 +810,78 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
endif
if(.not. iuse)cycle read_loop
+! Read the imager cluster information for the Cloud and Aerosol Detection Software.
+! Only channels 4 and 5 are used.
+
+ if ( iasi_cads ) then
+ call ufbseq(lnbufr,imager_info,33,7,iret,'IASIL1CS')
+ if (iret == 7 .and. imager_info(3,1) <= 100.0_r_kind .and. &
+ imager_info(3,1) >= zero .and. imager_coeff ) then ! if imager cluster info exists
+ imager_mean = zero
+ imager_std_dev = zero
+ imager_cluster_tot = zero
+ imager_cluster_flag = .TRUE.
+ imager_cluster_size = imager_info(3,1:7)
+ imager_cluster_size(:) = imager_cluster_size(:) / sum(imager_cluster_size(:))
+
+! Order clusters from largest (1) to smallest (7)
+ imager_cluster_sort: do i=1,7
+ j = maxloc(imager_cluster_size,dim=1,mask=imager_cluster_flag)
+ imager_cluster_index(i) = j
+ imager_cluster_flag(j) = .FALSE.
+ end do imager_cluster_sort
+
+! Convert from radiance to brightness temperature for mean and standard deviation used by CADS.
+! Imager cluster info added to data_all array
+
+ imager_cluster_info: do j=1,7
+ i = imager_cluster_index(j)
+
+ data_all(maxinfo+j,itx) = imager_cluster_size(i) ! Imager cluster fraction
+ imager_cluster_tot = imager_cluster_tot + imager_info(3,i)
+
+ iexponent = -(nint(imager_info(25,i))-5 ) ! channel 4 radiance for each cluster.
+ imager_info(26,i) = imager_info(26,i) * (ten ** iexponent)
+
+ iexponent = -(nint(imager_info(27,i))-5 ) ! channel 4 radiance std dev for each cluster.
+ imager_info(28,i) = imager_info(28,i) * (ten ** iexponent)
+
+ call crtm_planck_temperature(sensorindex_imager,2,imager_info(26,i),data_all(maxinfo+7+j,itx))
+ data_all(maxinfo+7+j,itx) = max(data_all(maxinfo+7+j,itx),zero)
+
+ iexponent = -(nint(imager_info(30,i))-5 ) ! channel 5 radiance for each cluster
+ imager_info(31,i) = imager_info(31,i) * (ten ** iexponent)
+
+ iexponent = -(nint(imager_info(32,i))-5 ) ! channel 5 radiance std dev for each cluser.
+ imager_info(33,i) = imager_info(33,i) * (ten ** iexponent)
+
+ call crtm_planck_temperature(sensorindex_imager,3,imager_info(31,i),data_all(maxinfo+14+j,itx))
+ data_all(maxinfo+14+j,itx) = max(data_all(maxinfo+14+j,itx),zero)
+
+ end do imager_cluster_info
+
+! Compute cluster averages for each channel
+
+ imager_mean(1) = sum(imager_cluster_size(:) * imager_info(26,:)) ! Channel 4 radiance cluster average
+ imager_std_dev(1) = sum(imager_cluster_size(:) * (imager_info(26,:)**2 + imager_info(28,:)**2)) - imager_mean(1)**2
+ imager_std_dev(1) = sqrt(max(imager_std_dev(1),zero)) ! Channel 4 radiance RMSE
+ call crtm_planck_temperature(sensorindex_imager,2,(imager_std_dev(1) + imager_mean(1)),imager_std_dev(1))
+ call crtm_planck_temperature(sensorindex_imager,2,imager_mean(1),imager_mean(1)) ! Channel 4 average BT
+ imager_std_dev(1) = imager_std_dev(1) - imager_mean(1) ! Channel 4 BT std dev
+ data_all(maxinfo+22,itx) = imager_std_dev(1)
+
+ imager_mean(2) = sum(imager_cluster_size(:) * imager_info(31,:)) ! Channel 5 radiance cluster average
+ imager_std_dev(2) = sum(imager_cluster_size(:) * (imager_info(31,:)**2 + imager_info(33,:)**2)) - imager_mean(1)**2
+ imager_std_dev(2) = sqrt(max(imager_std_dev(1),zero)) ! Channel 5 radiance RMSE
+ call crtm_planck_temperature(sensorindex_imager,3,(imager_std_dev(2) + imager_mean(2)),imager_std_dev(2))
+ call crtm_planck_temperature(sensorindex_imager,3,imager_mean(2),imager_mean(2)) ! Channel 5 average BT
+ imager_std_dev(2) = imager_std_dev(2) - imager_mean(2) ! Channel 5 BT std dev
+ data_all(maxinfo+23,itx) = imager_std_dev(2)
+
+ else ! Imager cluster information is missing. Set everything to zero
+ data_all(maxinfo+1 : maxinfo+25,itx) = zero
+ endif
+ endif ! iasi_cads = .true.
!
! interpolate NSST variables to Obs. location and get dtw, dtc, tz_tr
!
@@ -791,7 +916,8 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
data_all(18,itx)= ts(3) ! snow skin temperature
data_all(19,itx)= tsavg ! average skin temperature
data_all(20,itx)= vty ! vegetation type
- data_all(21,itx)= vfr ! vegetation fraction
+ !data_all(21,itx)= vfr ! vegetation fraction
+ data_all(21,itx)= cloud_frac(1) ! temporary place for cloud fraction
data_all(22,itx)= sty ! soil type
data_all(23,itx)= stp ! soil temperature
data_all(24,itx)= sm ! soil moisture
@@ -804,25 +930,27 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
data_all(31,itx)= dlat_earth_deg ! earth relative latitude (degrees)
if(dval_use)then
- data_all(32,itx)= val_iasi
- data_all(33,itx)= itt
+ data_all(maxinfo+cads_info+1,itx)= val_iasi
+ data_all(maxinfo+cads_info+2,itx)= itt
end if
if ( nst_gsi > 0 ) then
- data_all(maxinfo+1,itx) = tref ! foundation temperature
- data_all(maxinfo+2,itx) = dtw ! dt_warm at zob
- data_all(maxinfo+3,itx) = dtc ! dt_cool at zob
- data_all(maxinfo+4,itx) = tz_tr ! d(Tz)/d(Tr)
+ data_all(maxinfo+cads_info+dval_info+1,itx) = tref ! foundation temperature
+ data_all(maxinfo+cads_info+dval_info+2,itx) = dtw ! dt_warm at zob
+ data_all(maxinfo+cads_info+dval_info+3,itx) = dtc ! dt_cool at zob
+ data_all(maxinfo+cads_info+dval_info+4,itx) = tz_tr ! d(Tz)/d(Tr)
endif
! Put satinfo defined channel temperatures into data array
do l=1,satinfo_nchan
+ ! Prevent out of bounds reference from temperature
+ if ( bufr_index(l) == 0 ) cycle
i = bufr_index(l)
- if ( bufr_index(l) /= 0 ) then
+ if(i /= 0)then
data_all(l+nreal,itx) = temperature(i) ! brightness temerature
else
data_all(l+nreal,itx) = tbmin
- endif
+ end if
end do
nrec(itx)=irec
@@ -835,7 +963,7 @@ subroutine read_iasi(mype,val_iasi,ithin,isfcalc,rmesh,jsatid,gstime,&
end do ears_db_loop
- deallocate(temperature, allchan, bufr_chan_test)
+ deallocate(temperature, allchan, bufr_chan_test,scalef)
deallocate(channel_number,sc_index)
deallocate(bufr_index)
! deallocate crtm info
diff --git a/src/gsi/read_l2bufr_mod.f90 b/src/gsi/read_l2bufr_mod.f90
index e0619ed1a8..9c9ad73afe 100644
--- a/src/gsi/read_l2bufr_mod.f90
+++ b/src/gsi/read_l2bufr_mod.f90
@@ -56,9 +56,9 @@ module read_l2bufr_mod
public :: range_max,del_time,l2superob_only,elev_angle_max,del_azimuth
public :: minnum,del_range,del_elev
- public :: invtllv,radar_sites,radar_box,radar_rmesh,radar_zmesh
+ public :: invtllv,radar_sites,radar_box,radar_rmesh,radar_zmesh,radar_pmot
- integer(i_kind) minnum
+ integer(i_kind) minnum,radar_pmot
real(r_kind) del_azimuth,del_elev,del_range,del_time,elev_angle_max,range_max,radar_rmesh,radar_zmesh
logical l2superob_only,radar_sites,radar_box
@@ -100,6 +100,14 @@ subroutine initialize_superob_radar
radar_box=.false.
radar_rmesh=10._r_kind
radar_zmesh=500._r_kind
+
+! radar_pmot of 0,1,2,3 will save different sets of obs output
+! radar_pmot - all obs - thin obs
+! radar_pmot - all obs
+! radar_pmot - use obs
+! radar_pmot - use obs + thin obs
+
+ radar_pmot = 2
end subroutine initialize_superob_radar
subroutine radar_bufr_read_all(npe,mype)
@@ -749,6 +757,7 @@ subroutine radar_bufr_read_all(npe,mype)
write(6,*)' nobs_hrbin=',nobs_hrbin1
write(6,*)' nrange_max=',nrange_max1
end if
+ deallocate(icount)
! Prepare to create superobs and write out.
open(inbufr,file='radar_supobs_from_level2',form='unformatted',iostat=iret)
@@ -946,6 +955,7 @@ subroutine radar_bufr_read_all(npe,mype)
close(inbufr)
close(inbufr)
end if
+ deallocate(indx)
deallocate(bins_work,bins,ibins2)
if(l2superob_only) then
call mpi_finalize(ierror)
diff --git a/src/gsi/read_lidar.f90 b/src/gsi/read_lidar.f90
index 6d74de0802..ad5b27b784 100644
--- a/src/gsi/read_lidar.f90
+++ b/src/gsi/read_lidar.f90
@@ -172,7 +172,7 @@ subroutine read_lidar(nread,ndata,nodata,infile,obstype,lunout,twind,sis,nobs)
! add obs reference time, then subtract analysis time to get obs time relative to analysis
- time_correction=float(minobs-minan)*r60inv
+ time_correction=real(minobs-minan,r_kind)*r60inv
else
time_correction=zero
diff --git a/src/gsi/read_mitm_mxtm.f90 b/src/gsi/read_mitm_mxtm.f90
index fbfe310bd4..393e997e32 100644
--- a/src/gsi/read_mitm_mxtm.f90
+++ b/src/gsi/read_mitm_mxtm.f90
@@ -84,7 +84,7 @@ subroutine read_mitm_mxtm(nread,ndata,nodata,infile,obstype,lunout,gstime,sis,no
real(r_kind) :: stnelev
real(r_kind) :: usage,tsavg,ff10,sfcr,zz
real(r_kind) :: mxtmoe,mitmoe,oberr,qtflg
- real(r_kind),allocatable,dimension(:,:):: cdata_all,cdata_out
+ real(r_kind),allocatable,dimension(:,:):: cdata_all
integer(i_kind) :: ikx(100:199) !order number of report type in convinfo file
integer(i_kind) :: kxall(100:199)
@@ -407,19 +407,11 @@ subroutine read_mitm_mxtm(nread,ndata,nodata,infile,obstype,lunout,gstime,sis,no
ndata=iout
nodata=iout
- allocate(cdata_out(nreal,ndata))
- do i=1,ndata
- do k=1,nreal
- cdata_out(k,i)=cdata_all(k,i)
- end do
- end do
-
call count_obs(ndata,nreal,ilat,ilon,cdata_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon,ndata
- write(lunout) cdata_out
+ write(lunout) ((cdata_all(k,i),k=1,nreal),i=1,ndata)
deallocate(cdata_all)
- deallocate(cdata_out)
call destroy_rjlists
if (lhilbert) call destroy_hilbertcurve
diff --git a/src/gsi/read_nsstbufr.f90 b/src/gsi/read_nsstbufr.f90
index adfdee4f13..97096f3760 100644
--- a/src/gsi/read_nsstbufr.f90
+++ b/src/gsi/read_nsstbufr.f90
@@ -367,7 +367,7 @@ subroutine read_nsstbufr(nread,ndata,nodata,gstime,infile,obstype,lunout, &
if ( rsc > 60.0_r_kind .or. rsc < zero ) rsc = zero !second in real
call w3fs21(idate5,nmind)
- sstime=float(nmind)
+ sstime=real(nmind,r_kind)
tdiff=(sstime-gstime)*r60inv
@@ -542,9 +542,9 @@ subroutine read_nsstbufr(nread,ndata,nodata,gstime,infile,obstype,lunout, &
kx = 197
sstoe = one
elseif ( trim(subset) == 'NC031002' ) then ! TESAC
- if ( tpf(1,1) >= one .and. tpf(1,1) < 20.0_r_kind ) then
- zob = tpf(1,1)
- elseif ( tpf(1,1) >= zero .and. tpf(1,1) < one ) then
+ if ( tpf2(1,1) >= one .and. tpf2(1,1) < 20.0_r_kind ) then
+ zob = tpf2(1,1)
+ elseif ( tpf2(1,1) >= zero .and. tpf2(1,1) < one ) then
zob = one
endif
kx = 198
@@ -553,9 +553,9 @@ subroutine read_nsstbufr(nread,ndata,nodata,gstime,infile,obstype,lunout, &
kx = 199 ! classify argo & glider to be bathy type
sstoe = r0_6
elseif ( trim(subset) == 'NC031001' ) then ! BATHY
- if ( tpf(1,1) >= one .and. tpf(1,1) <= 20.0_r_kind ) then
- zob = tpf(1,1)
- elseif ( tpf(1,1) >= zero .and. tpf(1,1) < one ) then
+ if ( tpf2(1,1) >= one .and. tpf2(1,1) <= 20.0_r_kind ) then
+ zob = tpf2(1,1)
+ elseif ( tpf2(1,1) >= zero .and. tpf2(1,1) < one ) then
zob = one
endif
kx = 199
@@ -667,6 +667,7 @@ subroutine read_nsstbufr(nread,ndata,nodata,gstime,infile,obstype,lunout, &
! Close unit to bufr file
1020 continue
+ deallocate(data_all)
if (oberrflg) deallocate(etabl)
call closbf(lunin)
close(lunin)
diff --git a/src/gsi/read_obs.F90 b/src/gsi/read_obs.F90
index 53b0723953..f89b42e155 100644
--- a/src/gsi/read_obs.F90
+++ b/src/gsi/read_obs.F90
@@ -192,6 +192,7 @@ subroutine read_obs_check (lexist,filename,jsatid,dtype,minuse,nread)
if ( .not. l_use_dbz_directDA) then
if(trim(dtype) == 'dbz' )return
end if
+ if(trim(dtype) == 'fed' )return
! Use routine as usual
@@ -202,7 +203,6 @@ subroutine read_obs_check (lexist,filename,jsatid,dtype,minuse,nread)
call datelen(10)
call readmg(lnbufr,subset,idate,iret)
if(iret == 0)then
-
! Extract date and check for consistency with analysis date
if (idateiadateend) then
if(offtime_data) then
@@ -221,9 +221,8 @@ subroutine read_obs_check (lexist,filename,jsatid,dtype,minuse,nread)
lexist=.false.
end if
if(lexist)then
- if(jsatid == '')then
- kidsat=0
- else if(jsatid == 'metop-a')then
+ kidsat=0
+ if(jsatid == 'metop-a')then
kidsat=4
else if(jsatid == 'metop-b')then
kidsat=3
@@ -346,8 +345,8 @@ subroutine read_obs_check (lexist,filename,jsatid,dtype,minuse,nread)
call datelen(10)
if(kidsat /= 0)then
- lexist = .false.
- satloop: do while(ireadmg(lnbufr,subset,idate2) >= 0)
+ lexist = .false.
+ satloop: do while(ireadmg(lnbufr,subset,idate2) >= 0)
if(ireadsb(lnbufr)==0)then
call ufbint(lnbufr,satid,1,1,iret,'SAID')
end if
@@ -356,8 +355,8 @@ subroutine read_obs_check (lexist,filename,jsatid,dtype,minuse,nread)
exit satloop
end if
nread = nread + 1
- end do satloop
- else if(trim(filename) == 'prepbufr')then ! RTod: wired-in filename is not a good idea
+ end do satloop
+ else if(trim(filename) == 'prepbufr')then
lexist = .false.
fileloop: do while(ireadmg(lnbufr,subset,idate2) >= 0)
do while(ireadsb(lnbufr)>=0)
@@ -402,7 +401,8 @@ subroutine read_obs_check (lexist,filename,jsatid,dtype,minuse,nread)
(said == 44) .or. (said == 5) .or. (said == 41) .or. &
(said == 42) .or. (said == 43) .or. (said == 722) .or. &
(said == 723).or. (said == 265).or. (said == 266) .or. &
- (said == 267).or. (said == 268).or. (said == 269)) then
+ (said == 267).or. (said == 268).or. (said == 269) .or. &
+ (said == 803)) then
lexist=.true.
exit gpsloop
end if
@@ -438,10 +438,10 @@ subroutine read_obs_check (lexist,filename,jsatid,dtype,minuse,nread)
end do
nread = nread + 1
end do airploop
- else if(trim(filename) == 'satwndbufr')then
+ else if(index(filename,'satwnd') /=0 .or. index(filename,'satwhr') /=0) then
lexist = .false.
loop: do while(ireadmg(lnbufr,subset,idate2) >= 0)
-! 5 GOES-R AMVs (NC005030, NC005031, NC005032, NC005034 and NC005039)
+! 5 GOES-R AMVs (NC005030, NC005031, NC005032, NC005034, NC005039, NC005099)
! are added as the GOES-R bufr file provide do not contain other winds.
! May not be necessary with the operational satwnd BUFR
if(trim(subset) == 'NC005010' .or. trim(subset) == 'NC005011' .or.&
@@ -452,6 +452,7 @@ subroutine read_obs_check (lexist,filename,jsatid,dtype,minuse,nread)
trim(subset) == 'NC005030' .or. trim(subset) == 'NC005031' .or.&
trim(subset) == 'NC005032' .or. trim(subset) == 'NC005034' .or.&
trim(subset) == 'NC005039' .or. &
+ trim(subset) == 'NC005099' .or. &
trim(subset) == 'NC005090' .or. trim(subset) == 'NC005091' .or.&
trim(subset) == 'NC005067' .or. trim(subset) == 'NC005068' .or. trim(subset) == 'NC005069' .or.&
trim(subset) == 'NC005047' .or. trim(subset) == 'NC005048' .or. trim(subset) == 'NC005049' .or.&
@@ -894,6 +895,7 @@ subroutine read_obs(ndata,mype)
if(obstype == 'mls20' ) nmls_type=nmls_type+1
if(obstype == 'mls22' ) nmls_type=nmls_type+1
if(obstype == 'mls30' ) nmls_type=nmls_type+1
+ if(obstype == 'mls55' ) nmls_type=nmls_type+1
if(nmls_type>1) then
write(6,*) '******ERROR***********: there is more than one MLS data type, not allowed, please check'
call stop2(339)
@@ -913,7 +915,8 @@ subroutine read_obs(ndata,mype)
obstype == 'mitm' .or. obstype=='pmsl' .or. &
obstype == 'howv' .or. obstype=='tcamt' .or. &
obstype=='lcbas' .or. obstype=='cldch' .or. obstype == 'larcglb' .or. &
- obstype=='uwnd10m' .or. obstype=='vwnd10m' .or. obstype=='dbz' ) then
+ obstype=='uwnd10m' .or. obstype=='vwnd10m' .or. obstype=='dbz' .or. &
+ obstype=='fed') then
ditype(i) = 'conv'
else if (obstype == 'swcp' .or. obstype == 'lwcp') then
ditype(i) = 'wcp'
@@ -937,6 +940,7 @@ subroutine read_obs(ndata,mype)
.or. obstype == 'ompsnp' &
.or. obstype == 'gome' &
.or. index(obstype, 'omps') /= 0 &
+ .or. index(obstype, 'omi' ) /= 0 &
.or. mls &
) then
ditype(i) = 'ozone'
@@ -1063,7 +1067,7 @@ subroutine read_obs(ndata,mype)
obstype == 'iasi' .or. obstype == 'atms') .and. &
(dplat(i) == 'n17' .or. dplat(i) == 'n18' .or. &
dplat(i) == 'n19' .or. dplat(i) == 'npp' .or. &
- dplat(i) == 'n20' .or. &
+ dplat(i) == 'n20' .or. dplat(i) == 'n21' .or. &
dplat(i) == 'metop-a' .or. dplat(i) == 'metop-b' .or. &
dplat(i) == 'metop-c')
! direct broadcast from NESDIS/UW
@@ -1074,7 +1078,7 @@ subroutine read_obs(ndata,mype)
obstype == 'iasi') .and. &
(dplat(i) == 'n17' .or. dplat(i) == 'n18' .or. &
dplat(i) == 'n19' .or. dplat(i) == 'npp' .or. &
- dplat(i) == 'n20' .or. &
+ dplat(i) == 'n20' .or. dplat(i) == 'n21' .or. &
dplat(i) == 'metop-a' .or. dplat(i) == 'metop-b' .or. &
dplat(i) == 'metop-c')
@@ -1083,7 +1087,12 @@ subroutine read_obs(ndata,mype)
if (ii>npem1) ii=0
if(mype==ii)then
call gsi_inquire(lenbytes,lexist,trim(dfile(i)),mype)
- call read_obs_check (lexist,trim(dfile(i)),dplat(i),dtype(i),minuse,read_rec1(i))
+
+ if (is_extOzone(dfile(i),obstype,dplat(i))) then
+ print*,'reading ',trim(dfile(i)),' ',obstype,' ',trim(dplat(i)),lexist,lenbytes
+ else
+ call read_obs_check (lexist,trim(dfile(i)),dplat(i),dtype(i),minuse,read_rec1(i))
+ endif
! If no data set starting record to be 999999. Note if this is not large
! enough code should still work - just does a bit more work.
@@ -1298,6 +1307,10 @@ subroutine read_obs(ndata,mype)
use_hgtl_full=.true.
if(belong(i))use_hgtl_full_proc=.true.
end if
+ if(obstype == 'fed')then
+ use_hgtl_full=.true.
+ if(belong(i))use_hgtl_full_proc=.true.
+ end if
if(obstype == 'sst')then
if(belong(i))use_sfc=.true.
endif
@@ -1493,7 +1506,7 @@ subroutine read_obs(ndata,mype)
else if(obstype == 'uv' .or. obstype == 'wspd10m' .or. &
obstype == 'uwnd10m' .or. obstype == 'vwnd10m') then
! Process satellite winds which seperate from prepbufr
- if ( index(infile,'satwnd') /=0 ) then
+ if ( index(infile,'satwnd') /=0 .or. index(infile,'satwhr') /=0 ) then
call read_satwnd(nread,npuse,nouse,infile,obstype,lunout,gstime,twind,sis,&
prsl_full,nobs_sub1(1,i))
string='READ_SATWND'
@@ -1516,10 +1529,6 @@ subroutine read_obs(ndata,mype)
call read_fl_hdob(nread,npuse,nouse,infile,obstype,lunout,gstime,twind,sis,&
prsl_full,nobs_sub1(1,i))
string='READ_FL_HDOB'
- else if (index(infile,'uprair') /=0)then
- call read_hdraob(nread,npuse,nouse,infile,obstype,lunout,twind,sis,&
- prsl_full,hgtl_full,nobs_sub1(1,i),read_rec(i))
- string='READ_UPRAIR'
else
call read_prepbufr(nread,npuse,nouse,infile,obstype,lunout,twind,sis,&
prsl_full,nobs_sub1(1,i),read_rec(i))
@@ -1593,6 +1602,7 @@ subroutine read_obs(ndata,mype)
string='READ_RADAR'
else if (sis == 'l2rw') then
if (l2rwthin)then
+ write(6,*)'READ_OBS: radial wind,read_radar_l2rw,dsis=',sis
call read_radar_l2rw(npuse,nouse,lunout,obstype,sis,nobs_sub1(1,i),hgtl_full)
string='READ_RADAR_L2RW_NOVADQC'
else
@@ -1635,6 +1645,12 @@ subroutine read_obs(ndata,mype)
endif
end if
+! Process flash extent density
+ else if (obstype == 'fed' ) then
+ print *, "calling read_fed"
+ call read_fed(nread,npuse,nouse,infile,obstype,lunout,twind,sis,nobs_sub1(1,i))
+ string='READ_FED'
+
! Process lagrangian data
else if (obstype == 'lag') then
call read_lag(nread,npuse,nouse,infile,lunout,obstype,&
@@ -1897,7 +1913,7 @@ subroutine read_obs(ndata,mype)
! Process satellite lightning observations (e.g. GOES/GLM)
else if(ditype(i) == 'light')then
if (obstype == 'goes_glm' ) then
- call read_goesglm(nread,ndata,nodata,infile,obstype,lunout,twind,sis)
+ call read_goesglm(nread,npuse,nodata,infile,obstype,lunout,twind,sis)
string='READ_GOESGLM'
endif
@@ -1942,6 +1958,7 @@ subroutine read_obs(ndata,mype)
! Deallocate arrays containing full horizontal surface fields
call destroy_sfc
! Sum and distribute number of obs read and used for each input ob group
+
call mpi_allreduce(ndata1,ndata,ndat*3,mpi_integer,mpi_sum,mpi_comm_world,&
ierror)
diff --git a/src/gsi/read_ozone.f90 b/src/gsi/read_ozone.f90
index 43dd16d5c8..8e9788d1cf 100644
--- a/src/gsi/read_ozone.f90
+++ b/src/gsi/read_ozone.f90
@@ -138,7 +138,7 @@ subroutine read_ozone(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
character(8) subset,subset6,subset8,subset8_ompsnp
character(49) ozstr,ozostr
character(63) lozstr
- character(51) ozgstr
+ character(51) ozgstr_v1,ozgstr_v2
character(27) ozgstr2
character(42) ozostr2
character(64) mlstr
@@ -165,11 +165,12 @@ subroutine read_ozone(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
! maximum number of observations set to
real(r_kind),allocatable,dimension(:,:):: ozout
- real(r_double) toq,poq
+ real(r_double) toq,poq,orbn
real(r_double),dimension(nloz_v6):: ozone_v6
real(r_double),dimension(29,nloz_v8):: ozone_v8
real(r_double),dimension(10):: hdroz
- real(r_double),dimension(10):: hdrozg
+ integer(i_kind):: nhdrozg
+ real(r_double),allocatable,dimension(:):: hdrozg
real(r_double),dimension(5):: hdrozg2
real(r_double),dimension(10):: hdrozo
real(r_double),dimension(8) :: hdrozo2
@@ -195,8 +196,10 @@ subroutine read_ozone(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
data lozstr &
/ 'OSP12 OSP11 OSP10 OSP9 OSP8 OSP7 OSP6 OSP5 OSP4 OSP3 OSP2 OSP1 ' /
- data ozgstr &
- / 'SAID CLAT CLON YEAR DOYR HOUR MINU SECO SOZA SOLAZI' /
+ data ozgstr_v1 &
+ / 'SAID CLAT CLON SOZA SOLAZI YEAR DOYR HOUR MINU SECO' /
+ data ozgstr_v2 &
+ / 'SAID CLAT CLON SOZA SOLAZI YEAR MNTH DAYS HOUR MINU SECO' /
data ozgstr2 &
/ 'CLDMNT SNOC ACIDX STKO FOVN' /
data ozostr &
@@ -482,8 +485,19 @@ subroutine read_ozone(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
cycle obsloop
endif
-! extract header information
- call ufbint(lunin,hdrozg,10,1,iret,ozgstr)
+! Test for BUFR version using ORBN mnemonic
+ call ufbint(lunin,orbn,1,1,iret,'ORBN')
+ if (orbn > 100000000.0_r_kind) then
+ nhdrozg = 11
+ else
+ nhdrozg = 10
+ endif
+ if (.not.allocated(hdrozg)) allocate(hdrozg(nhdrozg))
+ if (nhdrozg == 11) then
+ call ufbint(lunin,hdrozg,nhdrozg,1,iret,ozgstr_v2)
+ else
+ call ufbint(lunin,hdrozg,nhdrozg,1,iret,ozgstr_v1)
+ endif
call ufbint(lunin,hdrozg2,5,1,iret,ozgstr2)
rsat = hdrozg(1); ksatid=rsat
@@ -494,7 +508,7 @@ subroutine read_ozone(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
if (ksatid /= kidsat) cycle obsloop
! NESDIS does not put a flag for high SZA gome-2 data (SZA > 84 degree)
- if ( hdrozg(9) > r84 ) cycle obsloop
+ if ( hdrozg(4) > r84 ) cycle obsloop
nmrecs=nmrecs+nloz+1
@@ -520,15 +534,24 @@ subroutine read_ozone(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
endif
! Convert observation time to relative time
- idate5(1) = hdrozg(4) !year
- IDAYYR = hdrozg(5) ! Day of year
- JULIAN = -31739 + 1461 * (idate5(1) + 4799) /4 &
- -3 * ((idate5(1) + 4899) / 100) / 4 + IDAYYR
- call w3fs26(JULIAN,idate5(1),idate5(2),idate5(3),IDAYWK,IDAYYR)
-! idate5(2) month
-! idate5(3) day
- idate5(4) = hdrozg(6) !hour
- idate5(5) = hdrozg(7) !minute
+ if (nhdrozg == 11) then
+ idate5(1) = hdrozg(6) !year
+ idate5(2) = hdrozg(7) !month
+ idate5(3) = hdrozg(8) !day
+ idate5(4) = hdrozg(9) !hour
+ idate5(5) = hdrozg(10) !minute
+ else
+ idate5(1) = hdrozg(6) !year
+ IDAYYR = hdrozg(7) ! Day of year
+ JULIAN = -31739 + 1461 * (idate5(1) + 4799) /4 &
+ -3 * ((idate5(1) + 4899) / 100) / 4 + IDAYYR
+ call w3fs26(JULIAN,idate5(1),idate5(2),idate5(3),IDAYWK,IDAYYR)
+! idate5(2) month
+! idate5(3) day
+ idate5(4) = hdrozg(8) !hour
+ idate5(5) = hdrozg(9) !minute
+ endif
+
call w3fs21(idate5,nmind)
t4dv=real((nmind-iwinbgn),r_kind)*r60inv
sstime=real(nmind,r_kind)
@@ -574,8 +597,8 @@ subroutine read_ozone(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
ozout(5,itx)=dlon_earth_deg ! earth relative longitude (degrees)
ozout(6,itx)=dlat_earth_deg ! earth relative latitude (degrees)
ozout(7,itx)=toq ! total ozone error flag
- ozout(8,itx)=hdrozg(9) ! solar zenith angle
- ozout(9,itx)=hdrozg(10) ! solar azimuth angle
+ ozout(8,itx)=hdrozg(4) ! solar zenith angle
+ ozout(9,itx)=hdrozg(5) ! solar azimuth angle
ozout(10,itx)=hdrozg2(1) ! CLOUD AMOUNT IN SEGMENT
ozout(11,itx)=hdrozg2(2) ! SNOW COVER
ozout(12,itx)=hdrozg2(3) ! AEROSOL CONTAMINATION INDEX
@@ -624,7 +647,8 @@ subroutine read_ozone(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
call makegrids(rmesh,ithin,n_tbin=n_tbin)
! Set dependent variables and allocate arrays
- nreal=14
+! nreal=14 !orig
+ nreal=15 !emily (add AFBO)
nloz=0
nchanl=1
nozdat=nreal+nchanl
@@ -753,7 +777,9 @@ subroutine read_ozone(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
ozout(12,itx)=hdrozo2(2) ! aerosol index
ozout(13,itx)=hdrozo2(3) ! ascending/descending
ozout(14,itx)=hdrozo2(7) ! scan position
- ozout(15,itx)=totoz
+ ozout(15,itx)=hdrozo2(8) ! AFBO !emily
+ ozout(16,itx)=totoz !emily
+!orig ozout(15,itx)=totoz
! End of loop over observations
end do read_loop2
@@ -1056,7 +1082,7 @@ subroutine read_ozone(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
ozout(8,ndata)=usage1(k) !
ozout(9,ndata)=mlspres(k) ! mls pressure in log(cb)
ozout(10,ndata)=mlsozpc(k) ! ozone mixing ratio precision in ppmv
- ozout(11,ndata)=float(ipos(k)) ! pointer of obs level index in ozinfo.txt
+ ozout(11,ndata)=real(ipos(k),r_kind) ! pointer of obs level index in ozinfo.txt
ozout(12,ndata)=nloz ! # of mls vertical levels
ozout(nreal+1,ndata)=mlsoz(k) ! ozone mixing ratio in ppmv
end do
@@ -1220,7 +1246,7 @@ subroutine read_ozone(nread,ndata,nodata,jsatid,infile,gstime,lunout, &
ozout(8,ndata)=usage1(k) !
ozout(9,ndata)=log(press(k)) ! ompslp pressure in log(cb)
ozout(10,ndata)=omrstd(k)*ompslp_mult_fact ! ozone mixing ratio precision in ppmv
- ozout(11,ndata)=float(ipos(k)) ! pointer of obs level index in
+ ozout(11,ndata)=real(ipos(k),r_kind) ! pointer of obs level index in
! ozinfo.txt
ozout(12,ndata)=j !nloz ! # of ompslp vertical levels
ozout(13,ndata)=omr(k) ! ozone mixing ratio in ppmv
diff --git a/src/gsi/read_pblh.f90 b/src/gsi/read_pblh.f90
index a7b7c066a2..1ff2cd2c23 100644
--- a/src/gsi/read_pblh.f90
+++ b/src/gsi/read_pblh.f90
@@ -343,7 +343,7 @@ subroutine read_pblh(nread,ndata,nodata,infile,obstype,lunout,twindin,&
! Add obs reference time, then subtract analysis time to get obs time relative to analysis
- time_correction=float(minobs-minan)/60._r_kind
+ time_correction=real(minobs-minan,r_kind)/60._r_kind
else
time_correction=zero
diff --git a/src/gsi/read_prepbufr.f90 b/src/gsi/read_prepbufr.f90
index d2cb503926..7dc1c463bf 100644
--- a/src/gsi/read_prepbufr.f90
+++ b/src/gsi/read_prepbufr.f90
@@ -148,6 +148,11 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
!
! 2020-05-04 wu - no rotate_wind for fv3_regional
! 2020-09-05 CAPS(C. Tong) - add flag for new vadwind obs to assimilate around the analysis time only
+! 2023-03-23 draper - add code for processing T2m and q2m for global system
+! 2023-07-30 zhao - added code to extract obs of significant wave height (howvob) from bufr record
+! in prepbufr file for 3D analysis
+! 2024-01-11 zhao - added code to extract sensible temp (tdry) and tv flag
+! for moisture obs(qob) when running (2D/3D)RTMA
! input argument list:
! infile - unit from which to read BUFR data
@@ -185,6 +190,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
use obsmod, only: iadate,oberrflg,perturb_obs,perturb_fact,ran01dom,hilbert_curve
use obsmod, only: blacklst,offtime_data,bmiss,ext_sonde,time_offset, vad_near_analtime
+ use obsmod, only: reduce_diag
use aircraftinfo, only: aircraft_t_bc,aircraft_t_bc_pof,ntail,taillist,idx_tail,npredt,predt, &
aircraft_t_bc_ext,ntail_update,max_tail,nsort,itail_sort,idx_sort,timelist
use converr,only: etabl
@@ -198,8 +204,8 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
use convb_t,only: btabl_t
use convb_uv,only: btabl_uv
use gsi_4dvar, only: l4dvar,l4densvar,time_4dvar,winlen,thin4d
- use convthin, only: make3grids,map3grids,map3grids_m,del3grids,use_all
- use convthin_time, only: make3grids_tm,map3grids_tm,map3grids_m_tm,del3grids_tm,use_all_tm
+ use convthin, only: make3grids,map3grids_m,del3grids,use_all
+ use convthin_time, only: make3grids_tm,map3grids_m_tm,del3grids_tm,use_all_tm
use qcmod, only: errormod,errormod_aircraft,noiqc,newvad,njqc
use qcmod, only: pvis,pcldch,scale_cv,estvisoe,estcldchoe,vis_thres,cldch_thres
use qcmod, only: nrand
@@ -212,7 +218,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
use hilbertcurve,only: init_hilbertcurve, accum_hilbertcurve, &
apply_hilbertcurve,destroy_hilbertcurve
use ndfdgrids,only: init_ndfdgrid,destroy_ndfdgrid,relocsfcob,adjust_error
- use jfunc, only: tsensible
+ use jfunc, only: tsensible, hofx_2m_sfcfile
use deter_sfc_mod, only: deter_sfc_type,deter_sfc2
use gsi_nstcouplermod, only: nst_gsi,nstinfo
use gsi_nstcouplermod, only: gsi_nstcoupler_deter
@@ -221,6 +227,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
use adjust_cloudobs_mod, only: adjust_convcldobs,adjust_goescldobs
use mpimod, only: npe
use rapidrefresh_cldsurf_mod, only: i_gsdsfc_uselist,i_gsdqc,i_ens_mean
+ use rapidrefresh_cldsurf_mod, only: l_rtma3d, oerr_gust
use gsi_io, only: verbose
use phil2, only: denest ! hilbert curve
@@ -263,9 +270,9 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
logical tob,qob,uvob,spdob,sstob,pwob,psob,gustob,visob,tdob,mxtmob,mitmob,pmob,howvob,cldchob
logical metarcldobs,goesctpobs,tcamtob,lcbasob
logical outside,driftl,convobs,inflate_error
- logical sfctype
+ logical sfctype, global_2m_land
logical luse,ithinp,windcorr
- logical patch_fog
+ logical patch_fog,save_all
logical aircraftset,aircraftobs,aircraftobst,aircrafttype
logical acft_profl_file
logical,allocatable,dimension(:,:):: lmsg ! set true when convinfo entry id found in a message
@@ -287,17 +294,17 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
character(1) cdummy
logical lhilbert
- integer(i_kind) ireadmg,ireadsb,icntpnt,icntpnt2,icount,iiout
- integer(i_kind) lunin,i,maxobs,j,idomsfc,it29,nmsgmax,mxtb
+ integer(i_kind) ireadmg,ireadsb,iqm,iuse,pmot
+ integer(i_kind) lunin,i,maxobs,j,idomsfc,it29,nmsgmax,mxtb,maxall
integer(i_kind) kk,klon1,klat1,klonp1,klatp1
- integer(i_kind) nc,nx,isflg,ntread,itx,ii,ncsave
+ integer(i_kind) nc,isflg,ntread,ii,ncsave,nxdata,nx
integer(i_kind) ihh,idd,idate,iret,im,iy,k,levs
integer(i_kind) metarcldlevs,metarwthlevs,cldseqlevs,cld2seqlevs
integer(i_kind) kx,kx0,nreal,nchanl,ilat,ilon,ithin
integer(i_kind) cat,zqm,pwq,sstq,qm,lim_qm,lim_zqm,gustqm,visqm,tdqm,mxtmqm,mitmqm,howvqm,cldchqm
integer(i_kind) lim_tqm,lim_qqm
integer(i_kind) nlevp ! vertical level for thinning
- integer(i_kind) ntmp,iout
+ integer(i_kind) iout
integer(i_kind) pflag,irec,zflag
integer(i_kind) ntest,nvtest,iosub,ixsub,isubsub,iobsub
integer(i_kind) kl,k1,k2,k1_ps,k1_q,k1_t,k1_uv,k1_pw,k2_q,k2_t,k2_uv,k2_pw,k2_ps
@@ -314,7 +321,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
integer(i_kind),dimension(255):: pqm,qqm,tqm,wqm,pmq
integer(i_kind),dimension(nconvtype)::ntxall
integer(i_kind),dimension(nconvtype+1)::ntx
- integer(i_kind),allocatable,dimension(:):: isort,iloc,nrep
+ integer(i_kind),allocatable,dimension(:):: nrep
integer(i_kind),allocatable,dimension(:,:):: tab
integer(i_kind) ibfms,thisobtype_usage
integer(i_kind) iwmo,ios
@@ -334,7 +341,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
real(r_kind) del,terrmin,werrmin,perrmin,qerrmin,pwerrmin,del_ps,del_q,del_t,del_uv,del_pw
real(r_kind) pjbmin,qjbmin,tjbmin,wjbmin
real(r_kind) tsavg,ff10,sfcr,zz
- real(r_kind) crit1,timedif,xmesh,pmesh,pmot,ptime ! thinning parameter
+ real(r_kind) crit1,timedif,xmesh,pmesh,ptime ! thinning parameter
real(r_kind) time_correction
real(r_kind) tcamt,lcbas,ceiling
real(r_kind) tcamt_oe,lcbas_oe
@@ -378,12 +385,18 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
integer(i_kind) indexx
real(r_kind) dentrip,dentrip_tmp,vmin,vmax,rmesh_tmp,pmesh_tmp,prest
integer(i_kind) ntime_max,ntime_tmp,itype,ikx
+! integer(i_kind) numthin,numqc,numrem,numall
integer(i_kind),dimension(24) :: ntype_arr
integer(i_kind),allocatable,dimension(:,:) :: index_arr
real(r_kind),allocatable,dimension(:,:,:) :: data_hilb
real(r_kind),allocatable,dimension(:) :: rlat_hil,rlon_hil,height,wtob,wght_hilb
+ logical, allocatable,dimension(:) :: rusage,rthin
! end of block
+! for extracting sensible-vs-virtual temp obs
+ integer(i_kind),dimension(1,255):: tqm4q
+ real(r_kind),dimension(1,255):: tvflg4q
+ real(r_double),dimension(1,255):: tobs4q
! equivalence to handle character names
equivalence(r_prvstg(1,1),c_prvstg)
@@ -431,8 +444,10 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! character(len=8) :: cval
! equivalence (rval,cval)
! character(7) flnm
- integer:: icase,klev,ikkk,tkk
- real:: diffhgt,diffuu,diffvv
+
+ integer:: icase,klev,ikkk,tkk
+ real:: diffhgt,diffuu,diffvv
+ integer,dimension(3)::kcount
real(r_double),dimension(3,1500):: fcstdat
logical print_verbose
@@ -444,12 +459,14 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! Initialize variables
+ kcount=0
vdisterrmax=zero
zflag=0
nreal=0
satqc=zero
tob = obstype == 't'
- uvob = obstype == 'uv' ; if (twodvar_regional) uvob = uvob .or. obstype == 'wspd10m' .or. obstype == 'uwnd10m' .or. obstype == 'vwnd10m'
+ uvob = obstype == 'uv'
+ if (twodvar_regional) uvob = uvob .or. obstype == 'wspd10m' .or. obstype == 'uwnd10m' .or. obstype == 'vwnd10m'
spdob = obstype == 'spd'
psob = obstype == 'ps'
qob = obstype == 'q'
@@ -472,52 +489,96 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
tdob .or. mxtmob .or. mitmob .or. pmob .or. howvob .or. &
tcamtob .or. lcbasob .or. cldchob
aircraftobst=.false.
+ iqm = 0
+ iuse = 0
if(tob)then
nreal=25
+ iqm = 10
+ iuse = 12
else if(uvob) then
- nreal=27
+ nreal=26
+ iqm = 12
+ iuse = 14
else if(spdob) then
nreal=24
+ iqm = 11
+ iuse = 13
else if(psob) then
nreal=20
+ iqm=10
+ iuse = 12
else if(qob) then
nreal=26
+ iqm = 11
+ iuse = 13
else if(pwob) then
nreal=20
+ iqm = 9
+ iuse = 11
else if(sstob) then
if (nst_gsi > 0) then
nreal=18 + nstinfo
else
nreal=18
end if
+ iqm = 11
+ iuse = 13
else if(gustob) then
nreal=21
+ iqm = 11
+ iuse = 12
else if(visob) then
nreal=18
+ iqm = 9
+ iuse = 10
else if(tdob) then
nreal=25
+ iqm = 11
+ iuse = 13
else if(mxtmob) then
nreal=24
+ iqm = 10
+ iuse = 12
else if(mitmob) then
nreal=24
+ iqm = 10
+ iuse = 12
else if(pmob) then
nreal=24
+ iqm = 11
+ iuse = 13
else if(howvob) then
nreal=23
+ iqm = 9
+ iuse = 11
else if(metarcldobs) then
nreal=27
+ iqm = 0
+ iuse = 22
else if(goesctpobs) then
nreal=8
+ iqm = 0
+ iuse = 8
else if(tcamtob) then
nreal=20
+ iqm = 8
+ iuse = 9
else if(lcbasob) then
nreal=23
+ iqm = 8
+ iuse = 9
else if(cldchob) then
nreal=18
+ iqm = 9
+ iuse = 10
else
write(6,*) ' illegal obs type in READ_PREPBUFR ',obstype
call stop2(94)
end if
+ if(iuse < 1) then
+ write(6,*) ' mix up in read_prepbufr iuse '
+ call stop2(49)
+ end if
! Set qc limits based on noiqc flag
if (noiqc) then
@@ -603,10 +664,11 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
!! get message and subset counts
call getcount_bufr(infile,nmsgmax,mxtb)
- allocate(lmsg(nmsgmax,ntread),tab(mxtb,3),nrep(nmsgmax))
+ allocate(lmsg(nmsgmax,ntread),tab(mxtb,2),nrep(nmsgmax))
lmsg = .false.
maxobs=0
+ maxall=0
tab=0
nmsg=0
nrep=0
@@ -689,7 +751,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! identify drifting buoys - TYP=180/280 T29=562 and last three digits of SID between 500 and 999
! (see https://www.wmo.int/pages/prog/amp/mmop/wmo-number-rules.html) Set kx to 199/299
- if (id_drifter .and. (kx==180 .or. kx==280) .and. nint(hdr(3))==562) then
+ if (id_drifter .and. (kx==180 .or. kx==280) .and. nint(hdr(3),r_double)==562) then
rstation_id=hdr(4)
read(c_station_id,*,iostat=ios) iwmo
if (ios == 0 .and. iwmo > 0) then
@@ -699,7 +761,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
end if
end if
- if (id_ship .and. (kx==180) .and. (nint(hdr(3))==522 .or. nint(hdr(3))==523)) then
+ if (id_ship .and. (kx==180) .and. (nint(hdr(3),r_double)==522 .or. nint(hdr(3),r_double)==523)) then
rstation_id=hdr(4)
kx = kx + 18
end if
@@ -774,11 +836,12 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
end if
end if
end do matchloop
+ call ufbint(lunin,levdat,1,255,levs,levstr)
+ maxall=maxall+max(1,levs)
! Save information for next read
if(ncsave /= 0) then
- call ufbint(lunin,levdat,1,255,levs,levstr)
maxobs=maxobs+max(1,levs)
nx=1
if(ithin_conv(ncsave) > 0 .and. ithin_conv(ncsave) <5)then
@@ -788,7 +851,6 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
end if
tab(ntb,1)=ncsave
tab(ntb,2)=nx
- tab(ntb,3)=levs
lmsg(nmsg,nx) = .true.
end if
@@ -821,6 +883,9 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
glcd=-999._r_double
endif
+ if(print_verbose) write(6,'(1x,A,A,A,2(A,1x,F8.3))') 'read_prepbufr:', &
+ trim(adjustl(obstype)),':', ' vtcd= ',vtcd,' glcd= ',glcd
+
call init_rjlists
call init_aircraft_rjlists
if(i_gsdsfc_uselist==1) call init_gsd_sfcuselist
@@ -834,9 +899,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! loop over convinfo file entries; operate on matches
- allocate(cdata_all(nreal,maxobs),isort(maxobs))
- isort = 0
- cdata_all=zero
+ allocate(cdata_all(nreal,maxall),rusage(maxall),rthin(maxall))
nread=0
ntest=0
nvtest=0
@@ -844,22 +907,27 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
ilon=2
ilat=3
rmesh=zero
- pmot=zero
pmesh=zero
ptime=zero
xmesh=zero
pflag=0
+ save_all=.true.
+ rusage = .true.
+ rthin = .false.
+ ndata = 0
loop_convinfo: do nx=1, ntread
- use_all_tm = .true.
+ use_all_tm = .true.
use_all = .true.
ithin=0
+ pmot=0
if(nx > 1) then
nc=ntx(nx)
ithin=ithin_conv(nc)
+ pmot=nint(pmot_conv(nc))
if (ithin > 0 .and. ithin <5) then
rmesh=rmesh_conv(nc)
pmesh=pmesh_conv(nc)
- pmot=pmot_conv(nc)
+
ptime=ptime_conv(nc)
if(pmesh > zero .and. ithin ==1) then
pflag=1
@@ -903,10 +971,13 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
enddo
endif
endif
- if(print_verbose) write(6,*)'READ_PREPBUFR: at line 779: obstype,ictype(nc),rmesh,pflag,nlevp,pmesh,pmot,ptime=',&
- trim(ioctype(nc)),ictype(nc),rmesh,pflag,nlevp,pmesh,pmot,ptime,ithin
+ if(print_verbose) write(6,*)'READ_PREPBUFR: obstype,ictype(nc),rmesh,pflag,nlevp,pmesh,pmot,ptime=',&
+ trim(ioctype(nc)),ictype(nc),rmesh,pflag,nlevp,pmesh,pmot,ptime,ithin,ndata,nc
endif
endif
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all = .false.
+ if(pmot /= 2 .and. pmot /= 0)save_all=.true.
call closbf(lunin)
@@ -919,8 +990,6 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
ntb = 0
nmsg = 0
- icntpnt=0
- icntpnt2=0
disterrmax=-9999.0_r_kind
irec = 0
loop_msg: do while (ireadmg(lunin,subset,idate)== 0)
@@ -935,9 +1004,6 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
nmsg = nmsg+1
if(.not.lmsg(nmsg,nx)) then
- do i=ntb+1,ntb+nrep(nmsg)
- icntpnt2=icntpnt2+tab(i,3)
- end do
ntb=ntb+nrep(nmsg)
cycle loop_msg ! no useable reports this mesage, skip ahead report count
end if
@@ -946,10 +1012,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! use msg lookup table to decide which messages to skip
! use report id lookup table to only process matching reports
ntb = ntb+1
- if(icntpnt < icntpnt2)icntpnt=icntpnt2
- icntpnt2=icntpnt2+tab(ntb,3)
- nc=tab(ntb,1)
- if(nc <= 0 .or. tab(ntb,2) /= nx) cycle loop_readsb
+ if(tab(ntb,1) <= 0 .or. tab(ntb,2) /= nx) cycle loop_readsb
! Extract type, date, and location information
call ufbint(lunin,hdr,8,1,iret,hdstr)
@@ -968,7 +1031,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
!
! identify drifting buoys - TYP=180/280 T29=562 and last three digits of SID between 500 and 999
! (see https://www.wmo.int/pages/prog/amp/mmop/wmo-number-rules.html) Set kx to 199/299
- if (id_drifter .and. (kx==180 .or. kx==280) .and. nint(hdr(8))==562 ) then
+ if (id_drifter .and. (kx==180 .or. kx==280) .and. nint(hdr(8),r_double)==562) then
rstation_id=hdr(1)
read(c_station_id,*,iostat=ios) iwmo
if (ios == 0 .and. iwmo > 0) then
@@ -978,7 +1041,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
end if
end if
- if (id_ship .and. (kx==180) .and. (nint(hdr(8))==522 .or. nint(hdr(8))==523) ) then
+ if (id_ship .and. (kx==180) .and. (nint(hdr(8),r_double)==522 .or. nint(hdr(8),r_double)==523) ) then
rstation_id=hdr(1)
kx = kx + 18
end if
@@ -1067,7 +1130,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! Add obs reference time, then subtract analysis time to get obs time relative to analysis
- time_correction=float(minobs-minan)*r60inv
+ time_correction=real(minobs-minan,r_kind)*r60inv
else
time_correction=zero
@@ -1088,12 +1151,16 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! Balloon drift information available for these data
driftl=kx==120.or.kx==220.or.kx==221
+ nc=tab(ntb,1)
if (.not. (aircraft_t_bc .and. acft_profl_file)) then
if (l4dvar.or.l4densvar) then
if ((t4dvwinlen) .and. .not.driftl) cycle loop_readsb ! outside time window
else
- if((real(abs(time)) > real(ctwind(nc)) .or. real(abs(time)) > real(twindin)) &
- .and. .not. driftl)cycle loop_readsb ! outside time window
+ ! Fix to ensure end of time window is NOT included
+ if ((real(abs(time)) > real(ctwind(nc)) .or. real(time)==real(three) .or. &
+ real(abs(time)) > real(twindin)) .and. .not. driftl)cycle loop_readsb ! outside time window
+! if((real(abs(time)) > real(ctwind(nc)) .or. real(abs(time)) > real(twindin)) &
+! .and. .not. driftl)cycle loop_readsb ! outside time window
endif
timex=time
@@ -1131,6 +1198,11 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
if (howvob) call ufbint(lunin,owave,1,255,levs,owavestr)
if (cldchob) call ufbint(lunin,cldceilh,1,255,levs,cldceilhstr)
endif
+! Extract obs of howv in 3D Analysis
+! (if-block is to avoid potential issue if decoding the bufr record twice in 2DRTMA run)
+ if ( .not. twodvar_regional ) then
+ if (howvob) call ufbint(lunin,owave,1,255,levs,owavestr)
+ endif
if(kx==224 .and. newvad) then
call ufbint(lunin,fcstdat,3,255,levs,'UFC VFC TFC ')
end if
@@ -1178,7 +1250,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
enddo
do k=1,levs
ppb=obsdat(1,k)
- cat=nint(min(obsdat(10,k),qcmark_huge))
+ cat=nint(min(obsdat(10,k),qcmark_huge))
if ( cat /=0 ) cycle
ppb=max(zero,min(ppb,r2000))
if(ppb>=etabl_ps(itypex,1,1)) k1_ps=1
@@ -1201,12 +1273,11 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
obserr(1,k)=max(obserr(1,k),perrmin)
endif
! Surface pressure b
- var_jb(1,k)=(one-del_ps)*btabl_ps(itypex,k1_ps,ierr_ps)+del_ps*btabl_ps(itypex,k2_ps,ierr_ps)
+ var_jb(1,k)=(one-del_ps)*btabl_ps(itypex,k1_ps,ierr_ps)+del_ps*btabl_ps(itypex,k2_ps,ierr_ps)
var_jb(1,k)=max(var_jb(1,k),pjbmin)
if (var_jb(1,k) >=10.0_r_kind) var_jb(1,k)=zero
enddo
- endif
- if (tob) then
+ else if (tob) then
itypex=itypey
ierr_t=0
do i =1,maxsub_t
@@ -1256,8 +1327,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
var_jb(3,k)=max(var_jb(3,k),tjbmin)
if (var_jb(3,k) >=10.0_r_kind) var_jb(3,k)=zero
enddo
- endif
- if (qob) then
+ else if (qob) then
itypex=itypey
ierr_q=0
do i =1,maxsub_q
@@ -1310,8 +1380,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! write(6,*) 'READ_PREPBUFR:120_q,obserr,var_jb=',obserr(2,k),var_jb(2,k),ppb
! endif
enddo
- endif
- if (uvob) then
+ else if (uvob) then
itypex=itypey
ierr_uv=0
do i =1,maxsub_uv
@@ -1347,13 +1416,13 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
if (abs(ediff_uv) > tiny_r_kind) then
del_uv = (ppb-etabl_uv(itypex,k1_uv,1))/ediff_uv
else
- del_uv = huge_r_kind
+ del_uv = huge_r_kind
endif
del_uv=max(zero,min(del_uv,one))
! Wind error
! write(6,*) 'READ_PREPBUFR_UV:',itypex,k1_uv,itypey,k2_uv,ierr_uv,nc,kx,ppb
- obserr(5,k)=(one-del_uv)*etabl_uv(itypex,k1_uv,ierr_uv)+del_uv*etabl_uv(itypex,k2_uv,ierr_uv)
- obserr(5,k)=max(obserr(5,k),werrmin)
+ obserr(5,k)=(one-del_uv)*etabl_uv(itypex,k1_uv,ierr_uv)+del_uv*etabl_uv(itypex,k2_uv,ierr_uv)
+ obserr(5,k)=max(obserr(5,k),werrmin)
!Wind b
var_jb(5,k)=(one-del_uv)*btabl_uv(itypex,k1_uv,ierr_uv)+del_uv*btabl_uv(itypex,k2_uv,ierr_uv)
var_jb(5,k)=max(var_jb(5,k),wjbmin)
@@ -1362,8 +1431,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! write(6,*) 'READ_PREPBUFR:220_uv,obserr,var_jb=',obserr(5,k),var_jb(5,k),ppb,k2_uv,del_uv
! endif
enddo
- endif
- if (pwob) then
+ else if (pwob) then
itypex=itypey
ierr_pw=0
do i =1,maxsub_pw
@@ -1448,6 +1516,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
if(driftl)call ufbint(lunin,drfdat,8,255,iret,drift)
! raob level enhancement on temp and q obs
+! (note: levs is increased by sonde_ext, and not same as original value read from prepbufr)
if(ext_sonde .and. kx==120) call sonde_ext(obsdat,tpc,qcmark,obserr,drfdat,levs,kx,vtcd)
nread=nread+levs
@@ -1614,10 +1683,17 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
pmq(k)=nint(qcmark(8,k))
end do
+! 187, 181, and 183 are the screen-level obs over land
+! note: don't need the hofx_2m_sfcfile if set usage in convinfo, and qm updated in the input file
+ global_2m_land = ( (kx==187 .or. kx==181 .or. kx==183) .and. hofx_2m_sfcfile )
+
! If temperature ob, extract information regarding virtual
! versus sensible temperature
if(tob) then
- if (.not. twodvar_regional .or. .not.tsensible) then
+ ! use tvirtual if tsensible flag not set, and not in either 2Dregional or global_2m DA mode
+ ! for now, keeping 2m obs as sensible, for global system.
+ if ( (.not. tsensible) .and. .not. (twodvar_regional .or. global_2m_land) ) then
+
do k=1,levs
tvflg(k)=one ! initialize as sensible
do j=1,20
@@ -1638,8 +1714,8 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
qcmark(3,k)=min(tobaux(2,k,j),qcmark_huge)
tqm(k)=nint(qcmark(3,k))
exit
- endif
- endif
+ end if
+ end if
if (tpc(k,j)==vtcd) then
obsdat(3,k)=tobaux(1,k,j+1)
qcmark(3,k)=min(tobaux(2,k,j+1),qcmark_huge)
@@ -1651,6 +1727,25 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
end if
end if
+! If moisture ob (qob) and (2D/3D)RTMA, set tv flag information (based on tpc)
+! regarding virtual vs. sensible temperaure, to get tdry (if virtual temp
+! then compute tdry; if sensible temp, then tdry= tsen), then save tdry
+! in q-obsdaig file for RTMA offline Auto-QC.
+ if (qob .and. (l_rtma3d .or. twodvar_regional)) then
+ tobs4q(1,:) = bmiss
+ tqm4q(1,:) = bmiss
+ tvflg4q(1,:)= -one
+ do k=1,levs
+ tvflg4q(1,k)=one ! initialize as sensible
+ tobs4q(1,k)=obsdat(3,k) ! temp obs read in prepbufr
+ tqm4q(1,k)=tqm(k)
+ do j=1,20
+ if (tpc(k,j)==vtcd) tvflg4q(1,k)=zero ! reset flag if virtual
+ if (tpc(k,j)>=bmiss) exit ! end of stack
+ end do
+ end do
+ end if ! if qob & rtma
+
if(i_gsdqc==2) then
! AMV acceptance for all obs (E. James)
if (kx >= 240 .and. kx <= 260) then
@@ -1701,16 +1796,14 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
endif
end if
LOOP_K_LEVS: do k=1,levs
- if( zflag ==-1) then
- ppb=obsdat(1,k)*one_tenth
- else if(zflag ==1) then
- ppb=obsdat(4,k)
- endif
- if(kx==224 .and. newvad)then
- if(mod(k,6)/=0) cycle LOOP_K_LEVS
- end if
-
- icntpnt=icntpnt+1
+ if( zflag ==-1) then
+ ppb=obsdat(1,k)*one_tenth
+ else if(zflag ==1) then
+ ppb=obsdat(4,k)
+ endif
+ if(kx==224 .and. newvad)then
+ if(mod(k,6)/=0) cycle LOOP_K_LEVS
+ end if
! Extract quality marks
if(tob)then
@@ -1735,6 +1828,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
gustqm=0
if (kx==188 .or. kx==288 .or. kx==195 .or. kx==295 ) &
call get_gustqm(kx,c_station_id,c_prvstg,c_sprvstg,gustqm)
+ if ( l_rtma3d ) gustqm = 0 ! skipping get_gustqm for 3drtma run (missing list file)
qm=gustqm
else if(visob) then
visqm=0 ! need to fix this later
@@ -1827,7 +1921,10 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
if (l4dvar.or.l4densvar) then
if (t4dvwinlen) cycle LOOP_K_LEVS
else
- if (real(abs(time))>real(ctwind(nc)) .or. real(abs(time))>real(twindin)) cycle LOOP_K_LEVS
+ ! Fix to ensure end of time window is NOT included
+ if (real(abs(time)) > real(ctwind(nc)) .or. real(time)==real(three) .or. &
+ real(abs(time)) > real(twindin)) cycle LOOP_K_LEVS ! outside time window
+! if (real(abs(time))>real(ctwind(nc)) .or. real(abs(time))>real(twindin)) cycle LOOP_K_LEVS
endif
end if
@@ -1914,21 +2011,44 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! Missing Values ==> Cycling! In this case for howv only. #ww3
if (howvob .and. owave(1,k) > r0_1_bmiss) cycle LOOP_K_LEVS
+! Over-ride QM=9 and hard-wire errors for land obs and hofx_sfc_file option
+! Can be deleted once prepbufr processing updated.
+ if ( global_2m_land ) then
+ if (tob .and. qm==9 ) then
+ pqm(k)=2 ! otherwise, type 183 will be discarded.
+ qm=2
+ tqm(k)=2
+ if (kx==187) obserr(3,k)=2.0_r_double
+ if (kx==181) obserr(3,k)=2.0_r_double
+ if (kx==183) obserr(3,k)=2.0_r_double
+ endif
+ if (qob .and. qm == 9 ) then
+ qm = 2
+ ! qob err specified as fraction of qsat, multiplied by 10.
+ if (kx==187) obserr(2,k)=1.0_r_double
+ if (kx==181) obserr(2,k)=1.0_r_double
+ if (kx==183) obserr(2,k)=1.0_r_double
+ endif
+ endif
! Set usage variable
usage = zero
- if(icuse(nc) <= 0)usage=100._r_kind
- if(qm == 15 .or. qm == 12 .or. qm == 9)usage=100._r_kind
- if(qm >=lim_qm )usage=101._r_kind
- if(convobs .and. pqm(k) >=lim_qm )usage=102._r_kind
- if((kx>=192.and.kx<=195) .and. psob )usage=r100
- if (gustob .and. obsdat(8,k) > r0_1_bmiss) usage=103._r_kind
- if (visob .and. obsdat(9,k) > r0_1_bmiss) usage=103._r_kind
- if (tdob .and. obsdat(12,k) > r0_1_bmiss) usage=103._r_kind
- if (pmob .and. obsdat(13,k) > r0_1_bmiss) usage=103._r_kind
- if (mxtmob .and. maxtmint(1,k) > r0_1_bmiss) usage=103._r_kind
- if (mitmob .and. maxtmint(2,k) > r0_1_bmiss) usage=103._r_kind
- if (howvob .and. owave(1,k) > r0_1_bmiss) usage=103._r_kind
- if (cldchob .and. cldceilh(1,k) > r0_1_bmiss) usage=103._r_kind
+ if((gustob .and. obsdat(8,k) > r0_1_bmiss) .or. &
+ (visob .and. obsdat(9,k) > r0_1_bmiss) .or. &
+ (tdob .and. obsdat(12,k) > r0_1_bmiss) .or. &
+ (pmob .and. obsdat(13,k) > r0_1_bmiss) .or. &
+ (mxtmob .and. maxtmint(1,k) > r0_1_bmiss) .or. &
+ (mitmob .and. maxtmint(2,k) > r0_1_bmiss) .or. &
+ (howvob .and. owave(1,k) > r0_1_bmiss) .or. &
+ (cldchob .and. cldceilh(1,k) > r0_1_bmiss))then
+ usage=103._r_kind
+ else if(convobs .and. pqm(k) >=lim_qm )then
+ usage=102._r_kind
+ else if(qm >=min(lim_qm,8) )then
+ usage=101._r_kind
+ else if(icuse(nc) <= 0 .or. &
+ (kx>=192 .and. kx<=195 .and. psob))then
+ usage=100._r_kind
+ end if
if (sfctype) then
if (i_gsdsfc_uselist==1 ) then
@@ -1943,20 +2063,21 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
!retrieve wind sensor height
if (twodvar_regional) then
if ( kx==288.or.kx==295 .or. (gustob .and. (kx==188.or.kx==195)) ) then
- call find_wind_height(c_prvstg,c_sprvstg,windsensht)
+ call find_wind_height(c_prvstg,c_sprvstg,windsensht,kcount)
endif
endif
- endif
- if (sfctype .and. i_gsdqc==2) then ! filter bad 2-m dew point and 0 mesonet wind obs
- if (kx==288.or.kx==295) then ! for mesonet wind
- if(abs(obsdat(5,k))<0.01_r_kind .and. abs(obsdat(6,k))<0.01_r_kind) usage=115._r_kind
- endif
- if (qob .and. (kx >=180 .and. kx<=189) .and. obsdat(2,k) < 1.0e10_r_kind) then ! for 2-m dew point
- if(obsdat(12,k) < min(-40.0_r_kind,obsdat(3,k)-10.0_r_kind)) usage=116._r_kind ! < min(-40C or T-Td)
- if((obsdat(3,k)-obsdat(12,k)) > 70.0_r_kind) usage=117._r_kind ! <70C
- if(obsdat(12,k) > 32.2_r_kind) usage=118._r_kind ! > 90F
+ if(i_gsdqc==2) then ! filter bad 2-m dew point and 0 mesonet wind obs
+ if (kx==288.or.kx==295) then ! for mesonet wind
+ if(abs(obsdat(5,k))<0.01_r_kind .and. abs(obsdat(6,k))<0.01_r_kind) usage=115._r_kind
+ endif
+ if (qob .and. (kx >=180 .and. kx<=189) .and. obsdat(2,k) < 1.0e10_r_kind) then ! for 2-m dew point
+ if(obsdat(12,k) < min(-40.0_r_kind,obsdat(3,k)-10.0_r_kind)) usage=116._r_kind ! < min(-40C or T-Td)
+ if((obsdat(3,k)-obsdat(12,k)) > 70.0_r_kind) usage=117._r_kind ! <70C
+ if(obsdat(12,k) > 32.2_r_kind) usage=118._r_kind ! > 90F
+ endif
endif
endif
+ ! to-do: should we add qob checks from above for landsfctype too?
if ((kx>129.and.kx<140).or.(kx>229.and.kx<240) ) then
call get_aircraft_usagerj(kx,obstype,c_station_id,usage)
@@ -1976,13 +2097,92 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! don't use MESONET psfc obs if 8th character of station id is "x")
if( kx==188 .and. psob .and. sidchr(8)=='x' ) usage=r100
+! Set inflate_error logical based on qm flag
+ inflate_error=.false.
+ if (qm==3 .or. qm==7) inflate_error=.true.
+
+ if(uvob) then
+ selev=stnelev
+ oelev=obsdat(4,k)
+ if(kx >= 280 .and. kx < 300 )then
+ if (twodvar_regional.and.(kx==288.or.kx==295)) then
+ oelev=windsensht+selev !windsensht: read in from prepbufr
+ else
+ oelev=r10+selev
+ endif
+ if (kx == 280 )then
+ it29=nint(hdr(8))
+ if(it29 == 522 .or. it29 == 523 .or. it29 == 531)then
+! oelev=r20+selev
+ oelev=r20
+ end if
+ end if
+
+ if (kx == 282) oelev=r20+selev
+ if (kx == 285 .or. kx == 289 .or. kx == 290) then
+ oelev=selev
+ selev=zero
+ endif
+ else
+ if((kx >= 221 .and. kx <= 229) &
+ .and. selev >= oelev) oelev=r10+selev
+ end if
+
+! Rotate winds to rotated coordinate
+ uob=obsdat(5,k)
+ vob=obsdat(6,k)
+ !* thin new VAD wind and generate VAD superob
+ if(kx==224.and.newvad)then
+ klev=k+5 !*average over 6 points
+ ! klev=k !* no average
+ if(klev>levs) cycle loop_readsb
+ diffuu=obsdat(5,k)-fcstdat(1,k)
+ diffvv=obsdat(6,k)-fcstdat(2,k)
+ if(sqrt(diffuu**2+diffvv**2)>10.0_r_kind) cycle loop_k_levs
+ if(abs(diffvv)>8.0_r_kind) cycle loop_k_levs
+ !if(abs(diffvv)>5.0.and.oelev<5000.0.and.fcstdat(3,k)>276.3) cycle loop_k_levs
+ if(oelev>7000.0_r_kind) cycle loop_k_levs
+ if(abs(diffvv)>5.0_r_kind.and.oelev<5000.0_r_kind) cycle loop_k_levs
+ ! write(6,*)'sliu diffuu,vv::',diffuu, diffvv
+ uob=zero
+ vob=zero
+ oelev=zero
+ tkk=0
+ do ikkk=k,klev
+ diffhgt=obsdat(4,ikkk)-obsdat(4,k)
+ if(diffhgt<301.0_r_kind)then
+ uob=uob+obsdat(5,ikkk)
+ vob=vob+obsdat(6,ikkk)
+ oelev=oelev+obsdat(4,ikkk)
+ tkk=tkk+1
+ end if
+ end do
+ uob=uob/tkk
+ vob=vob/tkk
+ oelev=oelev/tkk
+
+ diffuu=5.0_r_kind;diffvv=5.0_r_kind
+ diffhgt=0.0_r_kind
+ do ikkk=k,klev
+ diffuu=abs(obsdat(5,ikkk)-uob)
+ if(diffhgt5.0_r_kind)cycle LOOP_K_LEVS !* if u-u_avg>5.0, reject
+ if(tkk<3) cycle LOOP_K_LEVS !* obs numb<3, reject
+ !* unreasonable observation, will fix this in QC package
+ if(sqrt(uob**2+vob**2)>60.0_r_kind)cycle LOOP_readsb
+ end if
+ end if
! Get information from surface file necessary for conventional data here
+ if(icuse(nc) < 0)qm = 9
! Special block for data thinning - if requested
if (ithin > 0 .and. ithin <5 .and. usage <100.0_r_kind) then
! if (ithin > 0 .and. ithin <5) then
- ntmp=ndata ! counting moved to map3gridS
! Set data quality index for thinning
if (thin4d) then
@@ -2005,46 +2205,27 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
if (ptime >zero ) then
itime=int((abs(timedif)+three)/ptime)+1
- if(itime >ntime) itime=ntime
- call map3grids_tm(zflag,pflag,presl_thin,nlevp,dlat_earth,dlon_earth,&
- ppb,itime,crit1,ndata,iout,icntpnt,iiout,luse,.false.,.false.)
- if (.not. luse) then
- if(k==levs) then
- cycle loop_readsb
- else
- cycle LOOP_K_LEVS
- endif
- endif
- if(iiout > 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+1
- if(uvob)nodata=nodata+1
- endif
- isort(icntpnt)=iout
+ if(itime >ntime) itime=ntime
+ call map3grids_m_tm(zflag,save_all,pflag,presl_thin,nlevp, &
+ dlat_earth,dlon_earth,ppb,itime,crit1,ndata,&
+ luse,maxobs,rthin,.false.,.false.)
else
- call map3grids(zflag,pflag,presl_thin,nlevp,dlat_earth,dlon_earth,&
- ppb,crit1,ndata,iout,icntpnt,iiout,luse,.false.,.false.)
- if (.not. luse) then
- if(k==levs) then
- cycle loop_readsb
- else
- cycle LOOP_K_LEVS
- endif
- endif
- if(iiout > 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+1
- if(uvob)nodata=nodata+1
+ call map3grids_m(zflag,save_all,pflag,presl_thin,nlevp, &
+ dlat_earth,dlon_earth,ppb,crit1,ndata,&
+ luse,maxobs,rthin,.false.,.false.)
+ endif
+ if (.not. luse) then
+ if(k==levs) then
+ cycle loop_readsb
+ else
+ cycle LOOP_K_LEVS
endif
- isort(icntpnt)=iout
endif
+ if(rthin(ndata))usage=101._r_kind
else
ndata=ndata+1
- nodata=nodata+1
- if(uvob)nodata=nodata+1
- iout=ndata
- isort(icntpnt)=iout
endif
+ iout=ndata
if(ndata > maxobs) then
write(6,*)'READ_PREPBUFR: ***WARNING*** ndata > maxobs for ',obstype
@@ -2061,10 +2242,10 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! Extract pressure level and quality marks
dlnpob=log(plevs(k)) ! ln(pressure in cb)
-! Set inflate_error logical based on qm flag
- inflate_error=.false.
- if (qm==3 .or. qm==7) inflate_error=.true.
+ if(qm >= 8 .or. usage >= 100.0_r_kind)then
+ rusage(iout)=.false.
+ end if
! Temperature
if(tob) then
ppb=obsdat(1,k)
@@ -2116,6 +2297,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! Winds
else if(uvob) then
+
if (aircraftobs .and. aircraft_t_bc .and. acft_profl_file) then
call errormod_aircraft(pqm,wqm,levs,plevs,errout,k,presl,dpres,nsig,lim_qm,hdr3)
else
@@ -2124,80 +2306,6 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
woe=obserr(5,k)*errout
if (inflate_error) woe=woe*r1_2
if(obsdat(1,k) < r50)woe=woe*r1_2
- selev=stnelev
- oelev=obsdat(4,k)
- if(kx >= 280 .and. kx < 300 )then
- if (twodvar_regional.and.(kx==288.or.kx==295)) then
- oelev=windsensht+selev !windsensht: read in from prepbufr
- else
- oelev=r10+selev
- endif
- if (kx == 280 )then
- it29=nint(hdr(8))
- if(it29 == 522 .or. it29 == 523 .or. it29 == 531)then
-! oelev=r20+selev
- oelev=r20
- end if
- end if
-
- if (kx == 282) oelev=r20+selev
- if (kx == 285 .or. kx == 289 .or. kx == 290) then
- oelev=selev
- selev=zero
- endif
- else
- if((kx >= 221 .and. kx <= 229) &
- .and. selev >= oelev) oelev=r10+selev
- end if
-
-! Rotate winds to rotated coordinate
- uob=obsdat(5,k)
- vob=obsdat(6,k)
- !* thin new VAD wind and generate VAD superob
- if(kx==224.and.newvad)then
- klev=k+5 !*average over 6 points
- ! klev=k !* no average
- if(klev>levs) cycle loop_readsb
- diffuu=obsdat(5,k)-fcstdat(1,k)
- diffvv=obsdat(6,k)-fcstdat(2,k)
- if(sqrt(diffuu**2+diffvv**2)>10.0_r_kind) cycle loop_k_levs
- if(abs(diffvv)>8.0_r_kind) cycle loop_k_levs
- !if(abs(diffvv)>5.0.and.oelev<5000.0.and.fcstdat(3,k)>276.3) cycle loop_k_levs
- if(oelev>7000.0_r_kind) cycle loop_k_levs
- if(abs(diffvv)>5.0_r_kind.and.oelev<5000.0_r_kind) cycle loop_k_levs
- ! write(6,*)'sliu diffuu,vv::',diffuu, diffvv
- uob=0.0
- vob=0.0
- oelev=0.0
- tkk=0
- do ikkk=k,klev
- diffhgt=obsdat(4,ikkk)-obsdat(4,k)
- if(diffhgt<301.0_r_kind)then
- uob=uob+obsdat(5,ikkk)
- vob=vob+obsdat(6,ikkk)
- oelev=oelev+obsdat(4,ikkk)
- tkk=tkk+1
- end if
- end do
- uob=uob/tkk
- vob=vob/tkk
- oelev=oelev/tkk
-
- diffuu=5.0_r_kind;diffvv=5.0_r_kind
- diffhgt=0.0_r_kind
- do ikkk=k,klev
- diffuu=abs(obsdat(5,ikkk)-uob)
- if(diffhgt5.0_r_kind)cycle LOOP_K_LEVS !* if u-u_avg>5.0, reject
- if(tkk<3) cycle LOOP_K_LEVS !* obs numb<3, reject
- !* unreasonable observation, will fix this in QC package
- if(sqrt(uob**2+vob**2)>60.0_r_kind)cycle LOOP_readsb
- end if
-
if(regional .and. .not. fv3_regional)then
u0=uob
v0=vob
@@ -2210,6 +2318,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
end if
endif
+
cdata_all(1,iout)=woe ! wind error
cdata_all(2,iout)=dlon ! grid relative longitude
cdata_all(3,iout)=dlat ! grid relative latitude
@@ -2239,8 +2348,8 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
cdata_all(25,iout)=var_jb(5,k) ! non linear qc parameter
cdata_all(26,iout)=one ! hilbert curve weight, modified later
if(perturb_obs)then
- cdata_all(28,iout)=ran01dom()*perturb_fact ! u perturbation
- cdata_all(29,iout)=ran01dom()*perturb_fact ! v perturbation
+ cdata_all(27,iout)=ran01dom()*perturb_fact ! u perturbation
+ cdata_all(28,iout)=ran01dom()*perturb_fact ! v perturbation
endif
else if(spdob) then
@@ -2326,7 +2435,15 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
end if
qobcon=obsdat(2,k)*convert
tdry=r999
- if (tqm(k) 0.0_r_kind ) gustoe = oerr_gust
selev=stnelev
oelev=obsdat(4,k)
if(selev == oelev)oelev=r10+selev
@@ -2465,6 +2585,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
if ((kx==188).or.(kx==288) .or.(kx==195) .or.(kx==295)) then
! gustoe=2.5
gustoe=1.0
+ if ( l_rtma3d .and. oerr_gust > 0.0_r_kind ) gustoe = oerr_gust
windcorr=abs(obsdat(5,k))<1.0 .and. abs(obsdat(6,k))<1.0 .and. obsdat(8,k)>10.0
if (windcorr) gustoe=gustoe*1.5_r_kind
@@ -2781,7 +2902,6 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
hig_cldamt,hig_cldamt_qc,tcamt,lcbas,tcamt_qc,lcbas_qc,ceiling,stnelev)
end if
- if(tcamt_qc==15 .or. tcamt_qc==12 .or. tcamt_qc==9) usage=100._r_kind
tcamt_oe=20.0_r_kind
if(tcamt_qc==1) tcamt_oe=tcamt_oe*1.25_r_kind
if(tcamt_qc==2) tcamt_oe=tcamt_oe*1.50_r_kind
@@ -2818,7 +2938,8 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
low_cldamt,low_cldamt_qc,mid_cldamt,mid_cldamt_qc, &
hig_cldamt,hig_cldamt_qc,tcamt,lcbas,tcamt_qc,lcbas_qc,ceiling,stnelev)
- if(lcbas_qc==15 .or. lcbas_qc==12 .or. lcbas_qc==9) usage=100._r_kind
+ if(lcbas_qc >= 8) usage=100._r_kind
+ if(usage >= 100.0_r_kind)rusage(iout)=.false.
lcbas_oe=4500.0_r_kind
if(lcbas_qc==3) lcbas_oe=lcbas_oe*1.25_r_kind
if(lcbas_qc==4) lcbas_oe=lcbas_oe*1.5_r_kind
@@ -2925,51 +3046,82 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
deallocate(presl_thin)
call del3grids
endif
- if (.not.use_all_tm) then
- deallocate(presl_thin)
+ if(.not.use_all_tm) then
+ deallocate(presl_thin)
call del3grids_tm
endif
-
! Normal exit
enddo loop_convinfo! loops over convinfo entry matches
deallocate(lmsg,tab,nrep)
+
! Close unit to bufr file
call closbf(lunin)
close(lunin)
! Apply hilbert curve for cross validation if requested
- if(lhilbert) &
- call apply_hilbertcurve(maxobs,obstype,cdata_all(thisobtype_usage,1:maxobs))
+ if(lhilbert) then
+ call apply_hilbertcurve(ndata,obstype,cdata_all(thisobtype_usage,1:ndata))
-! Write header record and data to output file for further processing
- allocate(iloc(ndata))
- icount=0
- do i=1,maxobs
- if(isort(i) > 0)then
- icount=icount+1
- iloc(icount)=isort(i)
- end if
- end do
- if(ndata /= icount)then
- write(6,*) ' PREPBUFR: mix up in read_prepbufr ,ndata,icount ',ndata,icount
- call stop2(50)
+ do i=1,ndata
+ if(cdata_all(thisobtype_usage,i) >= 100._r_kind) rusage(i) = .false.
+ end do
end if
- allocate(cdata_out(nreal,ndata))
- do i=1,ndata
- itx=iloc(i)
- do k=1,nreal
- cdata_out(k,i)=cdata_all(k,itx)
+
+ nxdata=ndata
+ ndata=0
+ if(nxdata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,maxobs
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' prep ',trim(ioctype(nc)),ictype(nc),icsubtype(nc),numall,numrem,numqc,numthin
+! If thinned data set quality mark to 14
+ ! If flag to not save thinned data is set - compress data
+ do i=1,nxdata
+ ! pmot=0 - all obs - thin obs
+ ! pmot=1 - all obs
+ ! pmot=2 - use obs
+ ! pmot=3 - use obs + thin obs
+
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 1) .or. &
+ (pmot == 2 .and. (rusage(i) .and. .not. rthin(i))) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ if(rthin(i) .and. iqm > 0)cdata_all(iqm,i)=14
+ if(.not. rusage(i))cdata_all(iuse,i) = max(cdata_all(iuse,i),101.0_r_kind)
+ ndata=ndata+1
+ if(i > ndata)then
+ do k=1,nreal
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
+ end if
end do
- end do
- deallocate(iloc,isort,cdata_all)
+ if(uvob)then
+ nodata=nodata+2*ndata
+ else
+ nodata=nodata+ndata
+ end if
+ end if
+ deallocate(rusage,rthin)
+
! the following is gettin the types which will be applied hilbert curve to
! estimate the density
- if(obstype == 'uv') then
+ if(obstype == 'uv' .and. ndata > 0) then
vmin=-10.00_r_kind
vmax=18000.00_r_kind
nor=0
@@ -3046,7 +3198,8 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
endif
enddo
- write(6,*),'READ_PREPBUFR:dentrip,pmesh,rmesh,ndata=',dentrip,pmesh,rmesh,ntime_max,ndata
+ write(6,*),'READ_PREPBUFR: itype,dentrip,pmesh,rmesh,ndata=',&
+ itype,dentrip,pmesh,rmesh,ntime_max,ndata
if(dentrip >= one .and. pmesh >zero .and. rmesh >zero) then
allocate(data_hilb(3,ndata,6),index_arr(ndata,ntime_max))
@@ -3056,21 +3209,25 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
index_arr=0
do k=1,ndata
- ikx=nint(cdata_out(10,k))
- itype=ictype(ikx)
+ ikx=nint(cdata_all(10,k))
+ if (ikx>0) then
+ itype=ictype(ikx)
+ else
+ itype=0
+ endif
if( itype ==230 .or. itype ==231 .or. itype ==233) then
- prest=r10*exp(cdata_out(4,k))
+ prest=r10*exp(cdata_all(4,k))
if (prest <100.0_r_kind) cycle
if(ithin_conv(ikx) >=5) then
if(ptime_conv(ikx) >zero) then
- ntime=int(((cdata_out(9,k)-time_offset)+three)/ptime_conv(ikx))+1
+ ntime=int(((cdata_all(9,k)-time_offset)+three)/ptime_conv(ikx))+1
endif
if(ntime >ntime_max) ntime=ntime_max
if(ntime <0) ntime=1
ntype_arr(ntime)=ntype_arr(ntime)+1
ndata_hil=ntype_arr(ntime)
- data_hilb(1,ndata_hil,ntime)=cdata_out(20,k)
- data_hilb(2,ndata_hil,ntime)=cdata_out(19,k)
+ data_hilb(1,ndata_hil,ntime)=cdata_all(20,k)
+ data_hilb(2,ndata_hil,ntime)=cdata_all(19,k)
prest=prest*100.0_r_kind
if(prest >stndrd_atmos_ps) then
prest=zero
@@ -3088,7 +3245,7 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
write(6,*),'READ_PREPBUFR :something is wrong,lat,lon,prest=',&
data_hilb(1,ndata_hil,ntime),&
data_hilb(2,ndata_hil,ntime),&
- cdata_out(4,k),data_hilb(3,ndata_hil,ntime)
+ cdata_all(4,k),data_hilb(3,ndata_hil,ntime)
endif
endif
endif
@@ -3110,12 +3267,12 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
ndata_hil=0
deallocate(rlat_hil,rlon_hil,height,wtob)
endif
- enddo
+ enddo
deallocate(data_hilb,index_arr)
endif
do i=1,ndata
- cdata_out(26,i)=wght_hilb(i)
+ cdata_all(26,i)=wght_hilb(i)
enddo
deallocate(wght_hilb)
@@ -3130,26 +3287,24 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
if(metarcldobs .and. ndata > 0) then
if(i_ens_mean /= 1) then
maxobs=2000000
- allocate(cdata_all(nreal,maxobs))
- call reorg_metar_cloud(cdata_out,nreal,ndata,cdata_all,maxobs,iout)
+ allocate(cdata_out(nreal,maxobs))
+ call reorg_metar_cloud(cdata_all,nreal,ndata,cdata_out,maxobs,iout)
ndata=iout
- deallocate(cdata_out)
- allocate(cdata_out(nreal,ndata))
+ deallocate(cdata_all)
+ allocate(cdata_all(nreal,ndata))
do i=1,nreal
do j=1,ndata
- cdata_out(i,j)=cdata_all(i,j)
+ cdata_all(i,j)=cdata_out(i,j)
end do
end do
- deallocate(cdata_all)
+ deallocate(cdata_out)
endif
endif
- call count_obs(ndata,nreal,ilat,ilon,cdata_out,nobs)
+ call count_obs(ndata,nreal,ilat,ilon,cdata_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon,ndata
- write(lunout) cdata_out
+ write(lunout) ((cdata_all(k,i),k=1,nreal),i=1,ndata)
-
-
- deallocate(cdata_out)
+ deallocate(cdata_all)
call destroy_rjlists
call destroy_aircraft_rjlists
if(i_gsdsfc_uselist==1) call destroy_gsd_sfcuselist
@@ -3165,6 +3320,10 @@ subroutine read_prepbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
'nvtest,vdisterrmax=',ntest,vdisterrmax
if(print_verbose)write(6,*)'READ_PREPBUFR: closbf(',lunin,')'
+ if (twodvar_regional .and. (uvob .or. gustob .or. spdob)) then
+ write(6,*) 'kcount values from find wind height = ',kcount
+ end if
+
! End of routine
@@ -3283,8 +3442,8 @@ subroutine sonde_ext(obsdat,tpc,qcmark,obserr,drfdat,levsio,kx,vtcd)
write(6,*)'error in SONDE_EXT levs > 255'
return
endif
- obsdat(1,ll)=dpmdl(k)
- qcmark(1,ll) =max (qcmark(1,i),qcmark(1,im)) !PQM
+ obsdat(1,ll) = dpmdl(k)
+ qcmark(1,ll) = max (qcmark(1,i),qcmark(1,im)) !PQM
qcmark(2,ll) = bmiss
qcmark(3,ll) = bmiss
qcmark(4,ll) = bmiss
@@ -3297,21 +3456,21 @@ subroutine sonde_ext(obsdat,tpc,qcmark,obserr,drfdat,levsio,kx,vtcd)
wi=(dpobs(im)-prsltmp(k))/(dpobs(im)-dpobs(i))
!!! find tob, only bogus if both good obs and of the same type (sensible/virtual)
if( tqm(i)<4 .and. tqm(im)<4 .and. tvflg(i)==tvflg(im) ) then
- obsdat(3,ll)=obsdat(3,im)*wim + obsdat(3,i)*wi
- drfdat(1,ll) = drfdat(1,im)*wim + drfdat(1,i)*wi
- drfdat(2,ll) = drfdat(2,im)*wim + drfdat(2,i)*wi
- drfdat(3,ll) = drfdat(3,im)*wim + drfdat(3,i)*wi
- qcmark(3,ll) =max (qcmark(3,i),qcmark(3,im)) !TQM
- obserr(3,ll) =max (obserr(3,i),obserr(3,im)) ! TOE
+ obsdat(3,ll) = obsdat(3,im)*wim + obsdat(3,i)*wi
+ drfdat(1,ll) = drfdat(1,im)*wim + drfdat(1,i)*wi
+ drfdat(2,ll) = drfdat(2,im)*wim + drfdat(2,i)*wi
+ drfdat(3,ll) = drfdat(3,im)*wim + drfdat(3,i)*wi
+ qcmark(3,ll) = max (qcmark(3,i),qcmark(3,im)) !TQM
+ obserr(3,ll) = max (obserr(3,i),obserr(3,im)) ! TOE
endif
!!! find qob
if( qqm(i)<4 .and. qqm(im)<4 ) then
- obsdat(2,ll)=obsdat(2,im)*wim + obsdat(2,i)*wi
- drfdat(1,ll) = drfdat(1,im)*wim + drfdat(1,i)*wi
- drfdat(2,ll) = drfdat(2,im)*wim + drfdat(2,i)*wi
- drfdat(3,ll) = drfdat(3,im)*wim + drfdat(3,i)*wi
- qcmark(2,ll) =max (qcmark(2,i),qcmark(2,im)) !QQM
- obserr(2,ll) =max (obserr(2,i),obserr(2,im)) ! QOE
+ obsdat(2,ll) = obsdat(2,im)*wim + obsdat(2,i)*wi
+ drfdat(1,ll) = drfdat(1,im)*wim + drfdat(1,i)*wi
+ drfdat(2,ll) = drfdat(2,im)*wim + drfdat(2,i)*wi
+ drfdat(3,ll) = drfdat(3,im)*wim + drfdat(3,i)*wi
+ qcmark(2,ll) = max (qcmark(2,i),qcmark(2,im)) !QQM
+ obserr(2,ll) = max (obserr(2,i),obserr(2,im)) ! QOE
endif
!!! define zob
if( zqm(i)<4 .and. zqm(im)<4 ) then
diff --git a/src/gsi/read_radar.f90 b/src/gsi/read_radar.f90
index 8e5de5aff9..84a4f4fbcf 100644
--- a/src/gsi/read_radar.f90
+++ b/src/gsi/read_radar.f90
@@ -90,16 +90,15 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
eccentricity,somigliana,grav_ratio,grav, &
semi_major_axis,flattening,two
use qcmod, only: erradar_inflate,vadfile,newvad
- use obsmod, only: iadate,ianldate,l_foreaft_thin
+ use obsmod, only: iadate,ianldate,l_foreaft_thin,reduce_diag
use gsi_4dvar, only: l4dvar,l4densvar,iwinbgn,winlen,time_4dvar,thin4d
use gridmod, only: regional,nlat,nlon,tll2xy,rlats,rlons,rotate_wind_ll2xy,nsig,&
fv3_regional
use gridmod, only: wrf_nmm_regional,nems_nmmb_regional,cmaq_regional,wrf_mass_regional
use gridmod, only: fv3_regional
use convinfo, only: nconvtype,ctwind, &
- ncmiter,ncgroup,ncnumgrp,icuse,ictype,ioctype,ithin_conv,rmesh_conv,pmesh_conv
- use convthin, only: make3grids,map3grids,del3grids,use_all
- use deter_sfc_mod, only: deter_sfc2,deter_zsfc_model
+ ncmiter,ncgroup,ncnumgrp,icuse,ictype,ioctype,ithin_conv,rmesh_conv,pmesh_conv,pmot_conv
+ use convthin, only: make3grids,map3grids_m,del3grids,use_all
use mpimod, only: npe
use gsi_io, only: verbose
use mpimod, only: mype
@@ -107,6 +106,7 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
use directDA_radaruse_mod, only: l_correct_azmu, l_correct_tilt, i_correct_tilt, &
l_azm_east1st, l_plt_diag_rw
use directDA_radaruse_mod, only: l_use_rw_columntilt
+ use deter_sfc_mod, only: deter_sfc2,deter_zsfc_model
implicit none
@@ -154,7 +154,7 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
character(30) outmessage
character(255) filename
- integer(i_kind) lnbufr,i,j,k,maxobs,icntpnt,iiout,n,istop
+ integer(i_kind) lnbufr,i,j,k,maxobs,n,istop
integer(i_kind) nmrecs,ibadazm,ibadtilt,ibadrange,ibadwnd,ibaddist,ibadheight,ibadvad,kthin
integer(i_kind) iyr,imo,idy,ihr,imn,isc,ithin
integer(i_kind) ibadstaheight,ibaderror,notgood,idate,iheightbelowsta,ibadfit
@@ -269,9 +269,7 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
integer(i_kind) :: ii,jjj,nmissing,nirrr,noutside,ntimeout,nsubzero,iimax
integer(i_kind) ntdrvr_in,ntdrvr_kept,ntdrvr_thin1,ntdrvr_thin2
integer(i_kind) ntdrvr_thin2_foreswp,ntdrvr_thin2_aftswp
- integer(i_kind) maxout,maxdata
integer(i_kind) kk,klon1,klat1,klonp1,klatp1
- integer(i_kind),allocatable,dimension(:):: isort
real(r_single) elevmax,elevmin
real(r_single) thisrange,thisazimuth,thistilt
@@ -286,7 +284,7 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
real(r_kind),dimension(nsig):: zges,hges
real(r_kind) dx,dy,dx1,dy1,w00,w10,w01,w11
logical luse
- integer(i_kind) ntmp,iout
+ integer(i_kind) iout
integer(i_kind):: zflag
integer(i_kind) nlevz ! vertical level for thinning
real(r_kind) crit1,timedif
@@ -298,6 +296,11 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
real(r_kind) tdrele1,tdrele2,tdrele3
integer(i_kind) nswp,firstbeam,nforeswp,naftswp,nfore,naft,nswptype,irec
logical foreswp,aftswp
+
+ logical, allocatable,dimension(:) :: rusage,rthin
+ logical save_all
+! integer(i_kind) numthin,numqc,numrem
+ integer(i_kind) nxdata,pmot,numall
data lnbufr/10/
data hdrstr(1) / 'CLAT CLON SELV ANEL YEAR MNTH DAYS HOUR MINU MGPT' /
@@ -341,7 +344,7 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
if (.not.lexist1 .and. .not.lexist2 .and. .not.lexist3) return
eradkm=rearth*0.001_r_kind
- maxobs=2e8
+ maxobs=4e6
nreal=maxdat
nchanl=0
ilon=2
@@ -357,10 +360,10 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
hdrstr(2)='PTID YEAR MNTH DAYS HOUR MINU SECO CLAT CLON FLVLST ANAZ ANEL'
end if
- allocate(cdata_all(maxdat,maxobs),isort(maxobs))
+ allocate(cdata_all(maxdat,maxobs),rusage(maxobs),rthin(maxobs))
- isort = 0
- cdata_all=zero
+ rusage=.true.
+ rthin=.false.
if (trim(infile) /= 'tldplrbufr' .and. trim(infile) /= 'tldplrso') then
@@ -633,17 +636,25 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
nsuper2_kept=0
! LEVEL_TWO_READ: if(loop==0 .and. sis=='l2rw') then
- if(loop==0) outmessage='level 2 superobs:'
+ if(loop==0) outmessage='level 2 superobs:'
! Open sequential file containing superobs
open(lnbufr,file='radar_supobs_from_level2',form='unformatted')
rewind lnbufr
+ pmot=0
+ if(ikx /= 0)then
+ pmot=pmot_conv(ikx)
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all = .false.
+ if(pmot /= 2 .and. pmot /= 0)save_all=.true.
+ end if
! dist2max=-huge(dist2max)
! dist2min=huge(dist2min)
! Loop to read superobs data file
- do
+ superobs:do
+ if(ikx == 0) exit superobs
read(lnbufr,iostat=iret)this_staid,this_stalat,this_stalon,this_stahgt, &
thistime,thislat,thislon,thishgt,thisvr,corrected_azimuth,thiserr,corrected_tilt
if(iret/=0) exit
@@ -845,13 +856,14 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
level2(ivad)=level2(ivad)+1
nobs_box(irrr,iaaa,ivadz,ivad)=nobs_box(irrr,iaaa,ivadz,ivad)+1
ndata =min(ndata+1,maxobs)
- nodata =min(nodata+1,maxobs) !number of obs not used (no meaning here)
+ nodata =min(nodata+1,maxobs)
usage = zero
if(icuse(ikx) < 0)usage=r100
if(ncnumgrp(ikx) > 0 )then ! cross validation on
if(mod(ndata,ncnumgrp(ikx))== ncgroup(ikx)-1)usage=ncmiter(ikx)
end if
-
+ if(usage >= 100._r_kind) rusage(ndata)=.false.
+
call deter_sfc2(dlat_earth,dlon_earth,t4dv,idomsfc,skint,ff10,sfcr)
LEVEL_TWO_READ: if(loop==0 .and. sis=='l2rw') then
@@ -892,9 +904,10 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
notgood = notgood + 1
end if
- end do
+ end do superobs
close(lnbufr) ! A simple unformatted fortran file should not be mixed with a bufr I/O
+ nread=nsuper2_kept
LEVEL_TWO_READ_2: if(loop==0 .and. sis=='l2rw') then
write(6,*)'READ_RADAR: ',trim(outmessage),' reached eof on 2/2.5/3 superob radar file'
@@ -1087,6 +1100,10 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
if(trim(ioctype(i)) == trim(obstype))ikx = i
end do
if(ikx==0) cycle loop2
+ pmot=pmot_conv(ikx)
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all = .false.
+ if(pmot /= 2 .and. pmot /= 0)save_all=.true.
call w3fs21(idate5,minobs)
t4dv=real(minobs-iwinbgn,r_kind)*r60inv
if (l4dvar.or.l4densvar) then
@@ -1275,12 +1292,13 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
end if
nobs_box(irrr,iaaa,ivadz,ivad)=nobs_box(irrr,iaaa,ivadz,ivad)+1
ndata = min(ndata+1,maxobs)
- nodata = min(nodata+1,maxobs) !number of obs not used (no meaning here)
+ nodata = min(nodata+1,maxobs)
usage = zero
if(icuse(ikx) < 0)usage=r100
if(ncnumgrp(ikx) > 0 )then ! cross validation on
if(mod(ndata,ncnumgrp(ikx))== ncgroup(ikx)-1)usage=ncmiter(ikx)
end if
+ if(usage >= 100._r_kind) rusage(ndata)=.false.
call deter_sfc2(dlat_earth,dlon_earth,t4dv,idomsfc,skint,ff10,sfcr)
@@ -1325,7 +1343,7 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
! End of bufr read loop
end do loop2
end if
-
+
! Normal exit
! Close unit to bufr file
@@ -1335,8 +1353,8 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
write(6,*)'READ_RADAR: ',trim(outmessage),' reached eof on 2.5/3 superob radar file.'
- if(loop==1) write(6,*)'READ_RADAR: nsuper2_5_in,nsuper2_5_kept=',nsuper2_5_in,nsuper2_5_kept
- if(loop==2) write(6,*)'READ_RADAR: nsuper3_in,nsuper3_kept=',nsuper3_in,nsuper3_kept
+ if(loop==1)write(6,*)'READ_RADAR: nsuper2_5_in,nsuper2_5_kept=',nsuper2_5_in,nsuper2_5_kept
+ if(loop==2)write(6,*)'READ_RADAR: nsuper3_in,nsuper3_kept=',nsuper3_in,nsuper3_kept
write(6,*)'READ_RADAR: # no vad match =',novadmatch
write(6,*)'READ_RADAR: # out of vadrange=',ioutofvadrange
write(6,*)'READ_RADAR: # bad azimuths=',ibadazm
@@ -1586,6 +1604,10 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
if(trim(ioctype(i)) == trim(obstype))ikx = i
end do
if(ikx==0) cycle sb_report
+ pmot=pmot_conv(ikx)
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all = .false.
+ if(pmot /= 2 .and. pmot /= 0)save_all=.true.
! time window check
call w3fs21(idate5,minobs)
@@ -1957,9 +1979,10 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
re-compile GSI, re-run !!! <-- WARNING*** ***'
end if
ndata = min(ndata+1,maxobs)
- nodata = min(nodata+1,maxobs) !number of obs not used (no meaning here)
+ nodata = min(nodata+1,maxobs)
usage = zero
if(icuse(ikx) < 0)usage=r100
+ if(usage >= 100._r_kind) rusage(ndata)=.false.
call deter_sfc2(dlat_earth,dlon_earth,t4dv,idomsfc,skint,ff10,sfcr)
@@ -2154,18 +2177,14 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
ibadstaheight=0
notgood=0
notgood0=0
- nread=0
ntdrvr_in=0
ntdrvr_kept=0
ntdrvr_thin1=0
ntdrvr_thin2=0
ntdrvr_thin2_foreswp=0
ntdrvr_thin2_aftswp=0
- maxout=0
- maxdata=0
nmissing=0
subset_check(3)='NC006070'
- icntpnt=0
nswp=0
nforeswp=0
naftswp=0
@@ -2195,6 +2214,7 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
zflag=0
nlevz=nsig
endif
+
xmesh=rmesh
call make3grids(xmesh,nlevz)
allocate(zl_thin(nlevz))
@@ -2219,6 +2239,10 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
if(trim(ioctype(i)) == trim(obstype))ikx = i
end do
if(ikx == 0) return
+ pmot=pmot_conv(ikx)
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all = .false.
+ if(pmot /= 2 .and. pmot /= 0)save_all=.true.
call w3fs21(iadate,mincy) ! analysis time in minutes
@@ -2390,8 +2414,6 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
ntdrvr_kept=ntdrvr_kept+1
!#################### Data thinning ###################
- icntpnt=icntpnt+1
-
if(ithin > 0)then
if(zflag == 0)then
klon1= int(dlon); klat1= int(dlat)
@@ -2423,7 +2445,6 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
zobs = height
- ntmp=ndata ! counting moved to map3gridS
if (thin4d) then
timedif = zero
else
@@ -2431,27 +2452,19 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
endif
crit1 = timedif/r6+half
- call map3grids(1,zflag,zl_thin,nlevz,dlat_earth,dlon_earth,&
- zobs,crit1,ndata,iout,icntpnt,iiout,luse,.false.,.false.)
- maxout=max(maxout,iout)
- maxdata=max(maxdata,ndata)
+ call map3grids_m(1,save_all,zflag,zl_thin,nlevz, &
+ dlat_earth,dlon_earth,zobs,crit1,ndata,&
+ luse,maxobs,rthin,.false.,.false.)
if (.not. luse) then
ntdrvr_thin2=ntdrvr_thin2+1
cycle
endif
- if(iiout > 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+1
- endif
- isort(icntpnt)=iout
else
ndata =ndata+1
- nodata=nodata+1
- iout=ndata
- isort(icntpnt)=iout
endif
+ iout=ndata
if(ndata > maxobs) then
write(6,*)'READ_PREPBUFR: ***WARNING*** ndata > maxobs for ',obstype
@@ -2465,9 +2478,10 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
if(ncnumgrp(ikx) > 0 )then ! cross validation on
if(mod(ndata,ncnumgrp(ikx))== ncgroup(ikx)-1)usage=ncmiter(ikx)
end if
+ if(usage >= 100._r_kind) rusage(ndata)=.false.
call deter_zsfc_model(dlat,dlon,zsges)
-
+
! Get information from surface file necessary for conventional data here
call deter_sfc2(dlat_earth,dlon_earth,t4dv,idomsfc,skint,ff10,sfcr)
@@ -2508,7 +2522,7 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
end do ! end of loop, reading TDR so data files
close(lnbufr)
- else
+ else if (trim(infile) == 'tldplrbufr' ) then
nswptype=0
nmrecs=0
@@ -2659,6 +2673,10 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
if(trim(ioctype(i)) == trim(obstype) .and. kx == ictype(i))ikx = i
end do
if(ikx == 0) cycle loop4
+ pmot=pmot_conv(ikx)
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
call w3fs21(idate5,minobs)
t4dv=real(minobs-iwinbgn,r_kind)*r60inv
@@ -2784,8 +2802,9 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
nread=nread+1
! Select data every 3 km along each beam
if(MOD(INT(tdr_obs(1,k)-tdr_obs(1,1)),3000) < 100)then
- if(tdr_obs(3,k) >= 800.) nmissing=nmissing+1 !xx
- if(tdr_obs(3,k) < 800.) then
+ if(tdr_obs(3,k) >= 800.) then
+ nmissing=nmissing+1 !xx
+ else
ii=ii+1
dopbin(ii)=tdr_obs(3,k)
thisrange=tdr_obs(1,k)
@@ -2902,6 +2921,7 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
good=.true.
if(.not.good0) then
notgood0=notgood0+1
+ good=.false.
cycle
end if
! if data is good, load into output array
@@ -2910,7 +2930,7 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
ntdrvr_kept=ntdrvr_kept+1
!#################### Data thinning ###################
- icntpnt=icntpnt+1
+ if(ndata>maxobs) exit
if(ithin > 0)then
if(zflag == 0)then
@@ -2943,7 +2963,6 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
zobs = height
- ntmp=ndata ! counting moved to map3gridS
if (thin4d) then
timedif = zero
else
@@ -2951,10 +2970,9 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
endif
crit1 = timedif/r6+half
- call map3grids(1,zflag,zl_thin,nlevz,dlat_earth,dlon_earth,&
- zobs,crit1,ndata,iout,icntpnt,iiout,luse,foreswp,aftswp)
- maxout=max(maxout,iout)
- maxdata=max(maxdata,ndata)
+ call map3grids_m(1,save_all,zflag,zl_thin,nlevz, &
+ dlat_earth,dlon_earth,zobs,crit1,ndata,&
+ luse,maxobs,rthin,foreswp,aftswp)
if (.not. luse) then
if (foreswp) then
@@ -2965,18 +2983,11 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
ntdrvr_thin2=ntdrvr_thin2+1
cycle
endif
- if(iiout > 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+1
- endif
- isort(icntpnt)=iout
else
ndata =ndata+1
- nodata=nodata+1
- iout=ndata
- isort(icntpnt)=iout
endif
+ iout=ndata
if(ndata > maxobs) then
write(6,*)'READ_PREPBUFR: ***WARNING*** ndata > maxobs for ',obstype
@@ -2990,7 +3001,7 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
if(ncnumgrp(ikx) > 0 )then ! cross validation on
if(mod(ndata,ncnumgrp(ikx))== ncgroup(ikx)-1)usage=ncmiter(ikx)
end if
-
+ if(usage >= 100._r_kind) rusage(ndata)=.false.
call deter_zsfc_model(dlat,dlon,zsges)
! Get information from surface file necessary for conventional data here
@@ -3013,12 +3024,12 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
cdata(14)= skint ! skin temperature
cdata(15)= ff10 ! 10 meter wind factor
cdata(16)= sfcr ! surface roughness
- cdata(17)=dlon_earth_deg ! earth relative longitude (degrees)
- cdata(18)=dlat_earth_deg ! earth relative latitude (degrees)
- cdata(19)=dist ! range from radar in km (used to estimate beam spread)
- cdata(20)=zsges ! model elevation at radar site
- cdata(21)=thiserr
- cdata(22)=hdr(1)+three+one ! tail Doppler radar
+ cdata(17)= dlon_earth_deg ! earth relative longitude (degrees)
+ cdata(18)= dlat_earth_deg ! earth relative latitude (degrees)
+ cdata(19)= dist ! range from radar in km (used to estimate beam spread)
+ cdata(20)= zsges ! model elevation at radar site
+ cdata(21)= thiserr
+ cdata(22)= hdr(1)+three+one ! tail Doppler radar
do j=1,maxdat
cdata_all(j,iout)=cdata(j)
end do
@@ -3053,6 +3064,50 @@ subroutine read_radar(nread,ndata,nodata,infile,lunout,obstype,twind,sis,hgtl_fu
call del3grids
endif
+
+ nxdata=ndata
+ ndata=0
+ if(nxdata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,nxdata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' radar1 ',trim(ioctype(ikx)),ikx,numall,&
+! numrem,numqc,numthin,pmot
+
+! If flag to not save thinned data is set - compress data
+ do i=1,nxdata
+
+
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 1) .or. &
+ (pmot == 2 .and. (rusage(i) .and. .not. rthin(i))) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ if(rthin(i))cdata_all(12,i)=101._r_kind
+ ndata=ndata+1
+ do k=1,maxdat
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
+ end do
+ end if
+ nodata=nodata+ndata
+ deallocate(rusage,rthin)
+
+ write(6,*)'READ_RADAR: # records saved in radar1 = ', ndata
write(6,*)'READ_RADAR: # records(beams) read in nmrecs=', nmrecs
write(6,*)'READ_RADAR: # records out of time window =', ntimeout
write(6,*)'READ_RADAR: # records with bad tilt=',ibadtilt
@@ -3224,9 +3279,10 @@ subroutine read_radar_l2rw_novadqc(ndata,nodata,lunout,obstype,sis,nobs)
use gsi_4dvar, only: l4dvar,l4densvar,winlen,time_4dvar
use gridmod, only: regional,nlat,nlon,tll2xy,rlats,rlons,rotate_wind_ll2xy,&
fv3_regional
- use convinfo, only: nconvtype,ncmiter,ncgroup,ncnumgrp,icuse,ioctype
- use deter_sfc_mod, only: deter_sfc2
+ use convinfo, only: nconvtype,ncmiter,ncgroup,ncnumgrp,icuse,ioctype,pmot_conv
+ use deter_sfc_mod, only: deter_sfc2,deter_zsfc_model
use mpimod, only: npe
+ use obsmod, only: reduce_diag,time_offset
implicit none
@@ -3267,7 +3323,7 @@ subroutine read_radar_l2rw_novadqc(ndata,nodata,lunout,obstype,sis,nobs)
integer(i_kind) iret,kx0
integer(i_kind) nreal,nchanl,ilat,ilon,ikx
integer(i_kind) idomsfc
- real(r_kind) usage,ff10,sfcr,skint,t4dv,t4dvo,toff
+ real(r_kind) usage,ff10,sfcr,skint,t4dvo
real(r_kind) eradkm,dlat_earth,dlon_earth
real(r_kind) dlat,dlon,staheight,tiltangle,clon,slon,clat,slat
real(r_kind) timeo,clonh,slonh,clath,slath,cdist,dist
@@ -3295,8 +3351,11 @@ subroutine read_radar_l2rw_novadqc(ndata,nodata,lunout,obstype,sis,nobs)
real(r_kind) thishgt,thisvr,corrected_azimuth,thiserr,corrected_tilt
integer(i_kind) nsuper2_in,nsuper2_kept
real(r_kind) errzmax
+ logical, allocatable,dimension(:) :: rusage
+ integer(i_kind) numqc,numrem
+ integer(i_kind) nxdata,pmot,numall
+ logical save_all
- integer(i_kind),allocatable,dimension(:):: isort
! following variables are for fore/aft separation
integer(i_kind) irec
@@ -3318,11 +3377,9 @@ subroutine read_radar_l2rw_novadqc(ndata,nodata,lunout,obstype,sis,nobs)
dlatmin=huge(dlatmin)
dlonmin=huge(dlonmin)
- allocate(cdata_all(maxdat,maxobs),isort(maxobs))
-
- isort = 0
- cdata_all=zero
+ allocate(cdata_all(maxdat,maxobs),rusage(maxobs))
+ rusage=.true.
! Initialize variables
xscale=1000._r_kind
xscalei=one/xscale
@@ -3336,13 +3393,17 @@ subroutine read_radar_l2rw_novadqc(ndata,nodata,lunout,obstype,sis,nobs)
errzmax=zero
-
! First process any level 2 superobs.
! Initialize variables.
ikx=0
do i=1,nconvtype
if(trim(ioctype(i)) == trim(obstype))ikx = i
end do
+ if(ikx == 0) return
+ pmot=pmot_conv(ikx)
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
timemax=-huge(timemax)
timemin=huge(timemin)
@@ -3406,7 +3467,7 @@ subroutine read_radar_l2rw_novadqc(ndata,nodata,lunout,obstype,sis,nobs)
staheight=this_stahgt !station elevation
tiltangle=corrected_tilt*deg2rad
- t4dvo=toff+thistime
+ t4dvo=thistime+time_offset
timemax=max(timemax,t4dvo)
timemin=min(timemin,t4dvo)
@@ -3508,24 +3569,25 @@ subroutine read_radar_l2rw_novadqc(ndata,nodata,lunout,obstype,sis,nobs)
end if
good=.true.
if(.not.good0) then
+ good=.false.
notgood0=notgood0+1
cycle
- else
-
end if
! If data is good, load into output array
if(good) then
nsuper2_kept=nsuper2_kept+1
ndata =min(ndata+1,maxobs)
- nodata =min(nodata+1,maxobs) !number of obs not used (no meaninghere)
+ nodata =min(nodata+1,maxobs)
usage = zero
if(icuse(ikx) < 0)usage=r100
if(ncnumgrp(ikx) > 0 )then ! cross validation on
if(mod(ndata,ncnumgrp(ikx))== ncgroup(ikx)-1)usage=ncmiter(ikx)
end if
+ if(usage >= 100._r_kind)rusage(ndata)=.true.
- call deter_sfc2(dlat_earth,dlon_earth,t4dv,idomsfc,skint,ff10,sfcr)
+ call deter_sfc2(dlat_earth,dlon_earth,t4dvo,idomsfc,skint,ff10,sfcr)
+ call deter_zsfc_model(dlat,dlon,zsges)
cdata(1) = error ! wind obs error (m/s)
cdata(2) = dlon ! grid relative longitude
@@ -3533,7 +3595,7 @@ subroutine read_radar_l2rw_novadqc(ndata,nodata,lunout,obstype,sis,nobs)
cdata(4) = height ! obs absolute height (m)
cdata(5) = rwnd ! wind obs (m/s)
cdata(6) = azm*deg2rad ! azimuth angle (radians)
- cdata(7) = t4dv ! obs time (hour)
+ cdata(7) = t4dvo ! obs time (hour)
cdata(8) = ikx ! type
cdata(9) = tiltangle ! tilt angle (radians)
cdata(10)= staheight ! station elevation (m)
@@ -3559,8 +3621,46 @@ subroutine read_radar_l2rw_novadqc(ndata,nodata,lunout,obstype,sis,nobs)
end if
end do
+ nxdata=ndata
+ ndata=0
+ if(nxdata > 0)then
+! numqc=0
+! numrem=0
+! do i=1,nxdata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' radar3 ',numall,numrem,numqc
+! If flag to not save thinned data is set - compress data
+ if(pmot /= 1)then
+ do i=1,nxdata
+
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if( pmot == 0 .or. &
+ (pmot == 2 .and. rusage(i)) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ ndata=ndata+1
+ if(i > ndata)then
+ do k=1,maxdat
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
+ end if
+ end do
+ end if
+ end if
+ nodata=nodata+ndata
+
close(lnbufr) ! A simple unformatted fortran file should not be mixed with bufr I/O
+
write(6,*)'READ_RADAR_L2RW_NOVADQC: ',trim(outmessage),' reached eof on 2 superob radar file'
write(6,*)'READ_RADAR_L2RW_NOVADQC: nsuper2_in,nsuper2_kept=',nsuper2_in,nsuper2_kept
write(6,*)'READ_RADAR_L2RW_NOVADQC: # bad azimuths=',ibadazm
@@ -3583,7 +3683,7 @@ subroutine read_radar_l2rw_novadqc(ndata,nodata,lunout,obstype,sis,nobs)
call count_obs(ndata,maxdat,ilat,ilon,cdata_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon
write(lunout) ((cdata_all(k,i),k=1,maxdat),i=1,ndata)
- deallocate(cdata_all)
+ deallocate(cdata_all,rusage)
return
@@ -3597,15 +3697,16 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
use oneobmod, only: oneobtest,learthrel_rw
use gsi_4dvar, only: l4dvar,l4densvar,winlen,time_4dvar
use gridmod, only: regional,nlat,nlon,tll2xy,rlats,rlons,rotate_wind_ll2xy,nsig
- use obsmod, only: doradaroneob,oneobradid,time_offset
+ use obsmod, only: doradaroneob,oneobradid,time_offset,reduce_diag
use mpeu_util, only: gettablesize,gettable
use convinfo, only: nconvtype,icuse,ioctype
- use deter_sfc_mod, only: deter_sfc2
+ use deter_sfc_mod, only: deter_sfc2,deter_zsfc_model
use mpimod, only: npe
- use read_l2bufr_mod, only: radar_sites,radar_rmesh,radar_zmesh,elev_angle_max,del_time,range_max
+ use read_l2bufr_mod, only: radar_sites,radar_rmesh,radar_zmesh,elev_angle_max,del_time,range_max,radar_pmot
use constants, only: eccentricity,somigliana,grav_ratio,grav,semi_major_axis,flattening,grav_equator
use obsmod,only: radar_no_thinning,iadate
- use convthin, only: make3grids,map3grids
+ use deter_sfc_mod, only: deter_sfc2,deter_zsfc_model
+ use convthin, only: make3grids,map3grids_m
implicit none
@@ -3645,7 +3746,7 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
integer(i_kind) iret,kx0
integer(i_kind) nreal,nchanl,ilat,ilon,ikx
integer(i_kind) idomsfc
- real(r_kind) usage,ff10,sfcr,skint,t4dvo,toff
+ real(r_kind) usage,ff10,sfcr,skint,t4dvo
real(r_kind) eradkm,dlat_earth,dlon_earth
real(r_kind) dlat,dlon,staheight,tiltangle,clon,slon,clat,slat
real(r_kind) timeo,clonh,slonh,clath,slath,cdist,dist
@@ -3686,7 +3787,7 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
character(4),allocatable,dimension(:):: rsite
integer(i_kind),allocatable,dimension(:):: ruse
character(8) chdr2,subset
- real(r_double) rdisttest(n_gates_max),hdr(10),hdr2(12),rwnd0(3,n_gates_max)
+ real(r_double) rdisttest(n_gates_max),hdr(3),hdr2(12),rwnd0(3,n_gates_max)
character(4) stn_id
equivalence (chdr2,hdr2(1))
real(r_kind) stn_lat,stn_lon,stn_hgt,stn_az,stn_el,t,range,vrmax,vrmin,aactual,a43,b,c,selev0,celev0,thistiltr,epsh,h,ha,rlonloc,rlatloc
@@ -3695,16 +3796,17 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
real(r_kind):: relm,srlm,crlm,sph,cph,cc,anum,denom
real(r_kind) :: rmesh,xmesh,zmesh,dx,dy,dx1,dy1,w00,w01,w10,w11
real(r_kind), allocatable, dimension(:) :: zl_thin
- integer(i_kind) :: ithin,zflag,nlevz,icntpnt,klon1,klat1,kk,klatp1,klonp1
+ integer(i_kind) :: ithin,zflag,nlevz,klon1,klat1,kk,klatp1,klonp1
real(r_kind),dimension(nsig):: hges,zges
real(r_kind) sin2,termg,termr,termrg,zobs
- integer(i_kind) ntmp,iout,iiout,ntdrvr_thin2
+ integer(i_kind) iout,ntdrvr_thin2
real(r_kind) crit1,timedif
- integer(i_kind) maxout,maxdata
logical :: luse
- integer(i_kind) iyref,imref,idref,ihref,nout
-
- integer(i_kind),allocatable,dimension(:):: isort
+ integer(i_kind) iyref,imref,idref,ihref,nout
+ logical, allocatable,dimension(:) :: rusage,rthin
+ logical save_all
+! integer(i_kind) numthin,numqc,numrem
+ integer(i_kind) nxdata,pmot,numall
! following variables are for fore/aft separation
integer(i_kind) irec
@@ -3731,7 +3833,7 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
ilat=3
ikx=0
do j=1,nconvtype
- if(trim(ioctype(j)) == trim(obstype))ikx = j
+ if(trim(ioctype(j)) == trim(obstype))ikx = j
end do
iaaamax=-huge(iaaamax)
iaaamin=huge(iaaamin)
@@ -3739,10 +3841,10 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
dlonmax=-huge(dlonmax)
dlatmin=huge(dlatmin)
dlonmin=huge(dlonmin)
- allocate(cdata_all(maxdat,maxobs),isort(maxobs))
+ allocate(cdata_all(maxdat,maxobs),rusage(maxobs),rthin(maxobs))
- isort = 0
- cdata_all=zero
+ rthin=.false.
+ rusage=.true.
xscale=1000._r_kind
xscalei=one/xscale
max_rrr=nint(1000000.0_r_kind*xscalei)
@@ -3751,7 +3853,7 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
nmrecs=0
irec=0
errzmax=zero
-
+
timemax=-huge(timemax)
timemin=huge(timemin)
errmax=-huge(errmax)
@@ -3773,16 +3875,16 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
nsuper2_in=0
nsuper2_kept=0
ntdrvr_thin2=0
- maxout=0
- maxdata=0
- isort=0
- icntpnt=0
nout=0
if(loop==0) outmessage='level 2 superobs:'
rmesh=radar_rmesh
zmesh=radar_zmesh
nlevz=nint(16000._r_kind/zmesh)
xmesh=rmesh
+ pmot=radar_pmot
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
call make3grids(xmesh,nlevz)
allocate(zl_thin(nlevz))
zflag=1
@@ -3860,11 +3962,10 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
stn_lat=hdr2(2)
stn_lon=hdr2(3)
stn_hgt=hdr2(4)+hdr2(5)
- call ufbint(inbufr,hdr,10,1,levs, &
- 'SSTN YEAR MNTH DAYS HOUR MINU SECO ANAZ ANEL QCRW')
+ call ufbint(inbufr,hdr,3,1,levs,'ANAZ ANEL QCRW')
nradials_in=nradials_in+1
- stn_az=r90-hdr(8)
- stn_el=hdr(9)
+ stn_az=r90-hdr(1)
+ stn_el=hdr(2)
call ufbint(inbufr,rwnd0,3,n_gates_max,n_gates,'DIST125M DMVR DVSW')
do i=1,n_gates
range=distfact*rwnd0(1,i)
@@ -3972,7 +4073,7 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
slat=sin(dlat_earth)
staheight=this_stahgt !station elevation
tiltangle=corrected_tilt*deg2rad
- t4dvo=toff+thistime
+ t4dvo=time_offset+thistime
timemax=max(timemax,t4dvo)
timemin=min(timemin,t4dvo)
! Exclude data if it does not fall within time window
@@ -4030,7 +4131,7 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
azm=azm_earth
end if
!#################### Data thinning ###################
- icntpnt=icntpnt+1
+ if(ndata>maxobs) exit
ithin=1 !number of obs to keep per grid box
if(radar_no_thinning) then
ithin=-1
@@ -4064,32 +4165,23 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
end do
endif
zobs = height
- ntmp=ndata ! counting moved to map3gridS
if (l4dvar) then
timedif = zero
else
- timedif=abs(t4dvo-toff)
+ timedif=abs(t4dvo-time_offset)
endif
crit1 = timedif/r6+half
- call map3grids(1,zflag,zl_thin,nlevz,dlat_earth,dlon_earth,&
- zobs,crit1,ndata,iout,icntpnt,iiout,luse, .false., .false.)
- maxout=max(maxout,iout)
- maxdata=max(maxdata,ndata)
+ call map3grids_m(1,save_all,zflag,zl_thin,nlevz, &
+ dlat_earth,dlon_earth,zobs,crit1,ndata,&
+ luse,maxobs,rthin,.false.,.false.)
if (.not. luse) then
ntdrvr_thin2=ntdrvr_thin2+1
cycle
endif
- if(iiout > 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+1
- endif
- isort(icntpnt)=iout
else
ndata =ndata+1
- nodata=nodata+1
- iout=ndata
- isort(icntpnt)=iout
endif
+ iout=ndata
!#################### Data thinning ###################
if(.not. oneobtest) then
iaaa=azm/(r360/(r8*irrr))
@@ -4137,7 +4229,14 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
if(good) then
usage = zero
- if(icuse(ikx) < 0)usage=r100
+ if(icuse(ikx) < 0)then
+ rusage(ndata)=.false.
+ usage=r100
+ end if
+
+! Get information from surface file necessary for conventional data here
+ call deter_zsfc_model(dlat,dlon,zsges)
+ call deter_sfc2(dlat_earth,dlon_earth,t4dvo,idomsfc,skint,ff10,sfcr)
nsuper2_kept=nsuper2_kept+1
cdata(1) = error ! wind obs error (m/s)
@@ -4146,7 +4245,7 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
cdata(4) = height ! obs absolute height (m)
cdata(5) = rwnd ! wind obs (m/s)
cdata(6) = azm*deg2rad ! azimuth angle (radians)
- cdata(7) = t4dvo+time_offset ! obs time (hour)
+ cdata(7) = t4dvo ! obs time (hour)
cdata(8) = ikx ! type
cdata(9) = tiltangle ! tilt angle (radians)
cdata(10)= staheight ! station elevation (m)
@@ -4172,23 +4271,68 @@ subroutine read_radar_l2rw(ndata,nodata,lunout,obstype,sis,nobs,hgtl_full)
end do
end do
close(lnbufr) ! A simple unformatted fortran file should not be mixed with bufr I/O
- write(6,*)'READ_RADAR_L2RW_NOVADQC: ',trim(outmessage),' reached eof on 2 superob radar file'
- write(6,*)'READ_RADAR_L2RW_NOVADQC: nsuper2_in,nsuper2_kept=',nsuper2_in,nsuper2_kept
- write(6,*)'READ_RADAR_L2RW_NOVADQC: # bad winds =',ibadwnd,nobs_badvr,nobs_badsr
- write(6,*)'READ_RADAR_L2RW_NOVADQC: # num thinned =',kthin,ntdrvr_thin2
- write(6,*)'READ_RADAR_L2RW_NOVADQC: timemin,max =',timemin,timemax
- write(6,*)'READ_RADAR_L2RW_NOVADQC: errmin,max =',errmin,errmax
- write(6,*)'READ_RADAR_L2RW_NOVADQC: dlatmin,max,dlonmin,max=',dlatmin,dlatmax,dlonmin,dlonmax
+ nxdata=ndata
+ ndata=0
+ if(nxdata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,nxdata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' radar2 ',numall,numrem,numqc,numthin
+! If thinned data set quality mark to 14
+ if (ithin == 1 ) then
+ do i=1,nxdata
+ if(rthin(i))cdata_all(12,i)=101._r_kind
+ end do
+ end if
+
+! If flag to not save thinned data is set - compress data
+ if(pmot /= 1)then
+ do i=1,nxdata
+
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 2 .and. (rusage(i) .and. .not. rthin(i))) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ ndata=ndata+1
+ if(i > ndata)then
+ do k=1,maxdat
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
+ end if
+ end do
+ end if
+ end if
+ nodata=nodata+ndata
+ write(6,*)'READ_RADAR_L2RW: ',trim(outmessage),' reached eof on 2 superob radar file'
+ write(6,*)'READ_RADAR_L2RW: nsuper2_in,nsuper2_kept=',nsuper2_in,nsuper2_kept
+ write(6,*)'READ_RADAR_L2RW: # bad winds =',ibadwnd,nobs_badvr,nobs_badsr
+ write(6,*)'READ_RADAR_L2RW: # num thinned =',kthin,ntdrvr_thin2
+ write(6,*)'READ_RADAR_L2RW: timemin,max =',timemin,timemax
+ write(6,*)'READ_RADAR_L2RW: errmin,max =',errmin,errmax
+ write(6,*)'READ_RADAR_L2RW: dlatmin,max,dlonmin,max=',dlatmin,dlatmax,dlonmin,dlonmax
! Write observation to scratch file
+ deallocate(rusage,rthin)
call count_obs(ndata,maxdat,ilat,ilon,cdata_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon
- write(6,*) shape(cdata_all)
write(lunout) ((cdata_all(k,i),k=1,maxdat),i=1,ndata)
deallocate(cdata_all)
if (radar_sites) deallocate(rtable,rsite,ruse)
deallocate(zl_thin)
- deallocate(isort)
return
end subroutine read_radar_l2rw
diff --git a/src/gsi/read_radar_wind_ascii.f90 b/src/gsi/read_radar_wind_ascii.f90
index 2e1b06a50c..b79904273e 100644
--- a/src/gsi/read_radar_wind_ascii.f90
+++ b/src/gsi/read_radar_wind_ascii.f90
@@ -120,12 +120,12 @@ subroutine read_radar_wind_ascii(nread,ndata,nodata,infile,lunout,obstype,sis,hg
use gridmod, only: regional,tll2xy,rotate_wind_ll2xy,nsig,nlat,nlon,&
fv3_regional
use obsmod, only: iadate, &
- mintiltvr,maxtiltvr,minobrangevr,maxobrangevr, rmesh_vr,zmesh_vr,&
+ mintiltvr,maxtiltvr,minobrangevr,maxobrangevr,rmesh_vr,zmesh_vr,pmot_vr,&
doradaroneob,oneoblat,oneoblon,oneobheight,oneobradid
- use obsmod,only: radar_no_thinning
+ use obsmod,only: radar_no_thinning,reduce_diag
use gsi_4dvar, only: l4dvar,time_4dvar
use convinfo, only: nconvtype,ctwind,icuse,ioctype
- use convthin, only: make3grids,map3grids,del3grids,use_all
+ use convthin, only: make3grids,map3grids_m,del3grids,use_all
use read_l2bufr_mod, only: invtllv
use qcmod, only: erradar_inflate
use deter_sfc_mod, only: deter_sfc2,deter_zsfc_model
@@ -173,21 +173,19 @@ subroutine read_radar_wind_ascii(nread,ndata,nodata,infile,lunout,obstype,sis,hg
end type radar
!--Counters for diagnostics
- integer(i_kind) :: num_missing=0,numbadtime=0, & !counts
- num_badtilt=0,num_badrange=0, &
- ibadazm=0
+ integer(i_kind) :: num_missing=0,numbadtime=0, & !counts
+ num_badtilt=0,num_badrange=0, &
+ ibadazm=0
-integer(i_kind) :: ithin,zflag,nlevz,icntpnt,klon1,klat1,kk,klatp1,klonp1
-real(r_kind) :: rmesh,xmesh,zmesh,dx,dy,dx1,dy1,w00,w01,w10,w11
-real(r_kind), allocatable, dimension(:) :: zl_thin
+ integer(i_kind) :: ithin,zflag,nlevz,icntpnt,klon1,klat1,kk,klatp1,klonp1
+ real(r_kind) :: rmesh,xmesh,zmesh,dx,dy,dx1,dy1,w00,w01,w10,w11
+ real(r_kind), allocatable, dimension(:) :: zl_thin
real(r_kind),dimension(nsig):: hges,zges
real(r_kind) sin2,termg,termr,termrg,zobs,height
- integer(i_kind) ntmp,iout,iiout,ntdrvr_thin2
+ integer(i_kind) iout,ntdrvr_thin2
real(r_kind) crit1,timedif
real(r_kind),parameter:: r16000 = 16000.0_r_kind
-logical :: luse
- integer(i_kind) maxout,maxdata
- integer(i_kind),allocatable,dimension(:):: isort
+ logical :: luse
!--General declarations
integer(i_kind) :: ierror,lunrad,i,j,k,v,na,nb,nelv,nvol, &
@@ -201,12 +199,16 @@ subroutine read_radar_wind_ascii(nread,ndata,nodata,infile,lunout,obstype,sis,hg
real(r_kind) :: thistiltr,selev0,celev0,thisrange,this_stahgt,thishgt
real(r_kind) :: celev,selev,gamma,thisazimuthr,rlon0,t4dv, &
clat0,slat0,dlat,dlon,thiserr,thislon,thislat, &
- rlonloc,rlatloc,rlonglob,rlatglob,timeb,rad_per_meter
+ rlonloc,rlatloc,rlonglob,rlatglob,timeb,rad_per_meter
real(r_kind) :: azm,cosazm_earth,sinazm_earth,cosazm,sinazm
- real(r_kind) :: radartwindow
+ real(r_kind) :: radartwindow,usage
real(r_kind) :: rmins_an,rmins_ob
real(r_kind),allocatable,dimension(:,:):: cdata_all
real(r_double) rstation_id
+ logical, allocatable,dimension(:) :: rusage,rthin
+ logical save_all
+! integer(i_kind) numthin,numqc,numrem,numall
+ integer(i_kind) nxdata,pmot
character(8) cstaid
character(4) this_staid
@@ -217,7 +219,7 @@ subroutine read_radar_wind_ascii(nread,ndata,nodata,infile,lunout,obstype,sis,hg
type(radar),allocatable :: strct_in_vel(:,:)
-real(r_kind) :: mintilt,maxtilt,maxobrange,minobrange
+ real(r_kind) :: mintilt,maxtilt,maxobrange,minobrange
integer(i_kind) :: thin_freq=1
@@ -228,10 +230,10 @@ subroutine read_radar_wind_ascii(nread,ndata,nodata,infile,lunout,obstype,sis,hg
!-Check if radial velocity is in the convinfo file and extract necessary attributes
- ithin=1 !number of obs to keep per grid box
- if(radar_no_thinning) then
- ithin=-1
- endif
+ ithin=1 !number of obs to keep per grid box
+ if(radar_no_thinning) then
+ ithin=-1
+ endif
errmax=-huge(errmax)
errmin=huge(errmin)
@@ -241,13 +243,13 @@ subroutine read_radar_wind_ascii(nread,ndata,nodata,infile,lunout,obstype,sis,hg
if(trim(obstype) == trim(ioctype(i)) .and. abs(icuse(i))== 1) then
ikx=i
radartwindow=ctwind(ikx)*r60 !Time window units converted to minutes
- ! (default setting for dbz within convinfo is 0.05 hours)
- thiserr= 2_r_kind !1.75_r_kind !2_r_kind !Ob error (m/s) to use for radial velocity
- exit !Exit loop when finished with initial convinfo fields
+ ! (default setting for dbz within convinfo is 0.05 hours)
+ thiserr= 2_r_kind !1.75_r_kind !2_r_kind !Ob error (m/s) to use for radial velocity
+ exit !Exit loop when finished with initial convinfo fields
else if ( i==nconvtype ) then
write(6,*) 'READ_RADAR_WIND_ASCII: ERROR - OBSERVATION TYPE IS NOT PRESENT IN CONVINFO OR USE FLAG IS ZERO'
- write(6,*) 'READ_RADAR_WIND_ASCII: ABORTING read_radar_wind_ascii.f90 - NO VELOCITY OBS READ!'
- return
+ write(6,*) 'READ_RADAR_WIND_ASCII: ABORTING read_radar_wind_ascii.f90 - NO VELOCITY OBS READ!'
+ return
endif
end do
@@ -266,22 +268,19 @@ subroutine read_radar_wind_ascii(nread,ndata,nodata,infile,lunout,obstype,sis,hg
!--Allocate cdata_all array
- allocate(cdata_all(maxdat,maxobs),isort(maxobs))
+ allocate(cdata_all(maxdat,maxobs),rusage(maxobs),rthin(maxobs))
rmesh=rmesh_vr
zmesh=zmesh_vr
- maxout=0
- maxdata=0
- isort=0
ntdrvr_thin2=0
icntpnt=0
zflag=0
use_all=.true.
- if (ithin > 0) then
- write(6,*)'READ_RADAR: ithin,rmesh :',ithin,rmesh
+ if (ithin == 1) then
+ write(6,*)'READ_RADAR: rmesh :',rmesh
use_all=.false.
if(zflag == 0)then
nlevz=nsig
@@ -306,8 +305,8 @@ subroutine read_radar_wind_ascii(nread,ndata,nodata,infile,lunout,obstype,sis,hg
iostat=ierror,form='formatted')
- fileopen: if (ierror == 0) then
- read(lunrad,'(2i8)') nelv,nvol !read number of elevations and number of volumes
+ fileopen: if (ierror == 0) then
+ read(lunrad,'(2i8)') nelv,nvol !read number of elevations and number of volumes
!*************************IMPORTANT***************************!
@@ -319,302 +318,304 @@ subroutine read_radar_wind_ascii(nread,ndata,nodata,infile,lunout,obstype,sis,hg
!------Begin processing--------------------------!
+ rusage = .true.
+ rthin = .false.
+ use_all=.true.
- !-Obtain analysis time in minutes since reference date
- call w3fs21(iadate,mins_an) !mins_an -integer number of mins snce 01/01/1978
- rmins_an=mins_an !convert to real number
-
- volumes: do v=1,nvol
-
- read(lunrad,'(i8)') nelv
- allocate(strct_in_vel(1,nelv))
- tilts: do k=1,nelv
-
- read(lunrad,'(a4)') strct_in_vel(1,k)%radid
- read(lunrad,'(i8)') strct_in_vel(1,k)%vcpnum
- read(lunrad,'(6i8)') strct_in_vel(1,k)%year &
- ,strct_in_vel(1,k)%month &
- ,strct_in_vel(1,k)%day &
- ,strct_in_vel(1,k)%hour &
- ,strct_in_vel(1,k)%minute &
- ,strct_in_vel(1,k)%second
- read(lunrad,'(2f10.3,f10.1)') strct_in_vel(1,k)%radlat &
- ,strct_in_vel(1,k)%radlon &
- ,strct_in_vel(1,k)%radhgt
- read(lunrad,'(2f8.1)') strct_in_vel(1,k)%fstgatdis &
- ,strct_in_vel(1,k)%gateWidth
- read(lunrad,'(f8.3)') strct_in_vel(1,k)%elev_angle
- read(lunrad,'(2i8)') strct_in_vel(1,k)%num_beam &
- ,strct_in_vel(1,k)%num_gate
- na=strct_in_vel(1,k)%num_beam
- nb=strct_in_vel(1,k)%num_gate
-
- !******allocate arrays within radar data type**********!
- allocate(strct_in_vel(1,k)%azim(na))
- allocate(strct_in_vel(1,k)%field(nb,na))
- !******************************************************!
+ !-Obtain analysis time in minutes since reference date
+
+ call w3fs21(iadate,mins_an) !mins_an -integer number of mins snce 01/01/1978
+ rmins_an=mins_an !convert to real number
- read(lunrad,'(f8.3)') strct_in_vel(1,k)%nyq_vel
- read(lunrad,'(15f6.1)') (strct_in_vel(1,k)%azim(j),j=1,na)
- read(lunrad,'(20f6.1)') ((strct_in_vel(1,k)%field(i,j),i=1,nb),j=1,na)
-
-
- obdate(1)=strct_in_vel(1,k)%year
- obdate(2)=strct_in_vel(1,k)%month
- obdate(3)=strct_in_vel(1,k)%day
- obdate(4)=strct_in_vel(1,k)%hour
- obdate(5)=strct_in_vel(1,k)%minute
- call w3fs21(obdate,mins_ob) !mins_ob -integer number of mins snce 01/01/1978
- rmins_ob=mins_ob !convert to real number
- rmins_ob=rmins_ob+(strct_in_vel(1,k)%second*r60inv) !convert seconds to minutes and add to ob time
-
- !-Comparison is done in units of minutes
-
- timeb = rmins_ob-rmins_an
+ volumes: do v=1,nvol
+
+ read(lunrad,'(i8)') nelv
+ allocate(strct_in_vel(1,nelv))
+ tilts: do k=1,nelv
+
+ read(lunrad,'(a4)') strct_in_vel(1,k)%radid
+ read(lunrad,'(i8)') strct_in_vel(1,k)%vcpnum
+ read(lunrad,'(6i8)') strct_in_vel(1,k)%year &
+ ,strct_in_vel(1,k)%month &
+ ,strct_in_vel(1,k)%day &
+ ,strct_in_vel(1,k)%hour &
+ ,strct_in_vel(1,k)%minute &
+ ,strct_in_vel(1,k)%second
+ read(lunrad,'(2f10.3,f10.1)') strct_in_vel(1,k)%radlat &
+ ,strct_in_vel(1,k)%radlon &
+ ,strct_in_vel(1,k)%radhgt
+ read(lunrad,'(2f8.1)') strct_in_vel(1,k)%fstgatdis &
+ ,strct_in_vel(1,k)%gateWidth
+ read(lunrad,'(f8.3)') strct_in_vel(1,k)%elev_angle
+ read(lunrad,'(2i8)') strct_in_vel(1,k)%num_beam &
+ ,strct_in_vel(1,k)%num_gate
+ na=strct_in_vel(1,k)%num_beam
+ nb=strct_in_vel(1,k)%num_gate
+
+ !******allocate arrays within radar data type**********!
+ allocate(strct_in_vel(1,k)%azim(na))
+ allocate(strct_in_vel(1,k)%field(nb,na))
+ !******************************************************!
+
+ read(lunrad,'(f8.3)') strct_in_vel(1,k)%nyq_vel
+ read(lunrad,'(15f6.1)') (strct_in_vel(1,k)%azim(j),j=1,na)
+ read(lunrad,'(20f6.1)') ((strct_in_vel(1,k)%field(i,j),i=1,nb),j=1,na)
+
+
+ obdate(1)=strct_in_vel(1,k)%year
+ obdate(2)=strct_in_vel(1,k)%month
+ obdate(3)=strct_in_vel(1,k)%day
+ obdate(4)=strct_in_vel(1,k)%hour
+ obdate(5)=strct_in_vel(1,k)%minute
+ call w3fs21(obdate,mins_ob) !mins_ob -integer number of mins snce 01/01/1978
+ rmins_ob=mins_ob !convert to real number
+ rmins_ob=rmins_ob+(strct_in_vel(1,k)%second*r60inv) !convert seconds to minutes and add to ob time
+
+ !-Comparison is done in units of minutes
+
+ timeb = rmins_ob-rmins_an
- if(doradaroneob .and. (oneobradid /= strct_in_vel(1,k)%radid)) cycle tilts
+ if(doradaroneob .and. (oneobradid /= strct_in_vel(1,k)%radid)) cycle tilts
- if(abs(timeb) > abs(radartwindow)) then
- numbadtime=numbadtime+1
- cycle tilts !If not in time window, cycle the loop
- end if
- !--Time window check complete--!
+ if(abs(timeb) > abs(radartwindow)) then
+ numbadtime=numbadtime+1
+ cycle tilts !If not in time window, cycle the loop
+ end if
+ !--Time window check complete--!
- thistilt=strct_in_vel(1,k)%elev_angle
- if (thistilt <= maxtilt .and. thistilt >= mintilt) then
-
- gates: do i=1,strct_in_vel(1,k)%num_gate,thin_freq
- thisrange=strct_in_vel(1,k)%fstgatdis + float(i-1)*strct_in_vel(1,k)%gateWidth
-
- !-Check to make sure observations are within specified range
-
- if (thisrange <= maxobrange .and. thisrange >= minobrange) then
-
- azms: do j=1,strct_in_vel(1,k)%num_beam
-
- !-Check to see if this is a missing observation)
- nread=nread+1
- if ( strct_in_vel(1,k)%field(i,j) >= 999.0_r_kind ) then
- num_missing=num_missing+1
- cycle azms !No reason to process the ob if it is missing
- end if
-
- !--Find observation height using method from read_l2bufr_mod.f90
-
- this_stahgt=strct_in_vel(1,k)%radhgt
- aactual=rearth+this_stahgt
- a43=four_thirds*aactual
+ thistilt=strct_in_vel(1,k)%elev_angle
+ if (thistilt <= maxtilt .and. thistilt >= mintilt) then
+
+ gates: do i=1,strct_in_vel(1,k)%num_gate,thin_freq
+ thisrange=strct_in_vel(1,k)%fstgatdis + real(i-1,r_kind)*strct_in_vel(1,k)%gateWidth
+
+ !-Check to make sure observations are within specified range
+
+ if (thisrange <= maxobrange .and. thisrange >= minobrange) then
+
+ azms: do j=1,strct_in_vel(1,k)%num_beam
+
+ !-Check to see if this is a missing observation)
+ nread=nread+1
+ if ( strct_in_vel(1,k)%field(i,j) >= 999.0_r_kind ) then
+ num_missing=num_missing+1
+ cycle azms !No reason to process the ob if it is missing
+ end if
+
+ !--Find observation height using method from read_l2bufr_mod.f90
+
+ this_stahgt=strct_in_vel(1,k)%radhgt
+ aactual=rearth+this_stahgt
+ a43=four_thirds*aactual
thistiltr=thistilt*deg2rad
selev0=sin(thistiltr)
- celev0=cos(thistiltr)
- b=thisrange*(thisrange+two*aactual*selev0)
+ celev0=cos(thistiltr)
+ b=thisrange*(thisrange+two*aactual*selev0)
c=sqrt(aactual*aactual+b)
ha=b/(aactual+c)
epsh=(thisrange*thisrange-ha*ha)/(r8*aactual)
h=ha-epsh
- thishgt=this_stahgt+h
+ thishgt=this_stahgt+h
height=thishgt
- !--Find observation location using method from read_l2bufr_mod.f90
-
- !-Get corrected tilt angle
- celev=celev0
- selev=selev0
- celev=a43*celev0/(a43+h)
- selev=(thisrange*thisrange+h*h+two*a43*h)/(two*thisrange*(a43+h))
-
- gamma=half*thisrange*(celev0+celev)
-
+ !--Find observation location using method from read_l2bufr_mod.f90
+
+ !-Get corrected tilt angle
+ celev=celev0
+ selev=selev0
+ celev=a43*celev0/(a43+h)
+ selev=(thisrange*thisrange+h*h+two*a43*h)/(two*thisrange*(a43+h))
+
+ gamma=half*thisrange*(celev0+celev)
+
!-Get earth lat lon of observation
-
+
rlon0=deg2rad*strct_in_vel(1,k)%radlon
- clat0=cos(deg2rad*strct_in_vel(1,k)%radlat)
- slat0=sin(deg2rad*strct_in_vel(1,k)%radlat)
- thisazimuthr=(90.0_r_kind-strct_in_vel(1,k)%azim(j))*deg2rad !Storing as 90-azm to
- ! be consistent with
- ! read_l2bufr_mod.f90
- rad_per_meter=one/rearth
- rlonloc=rad_per_meter*gamma*cos(thisazimuthr)
+ clat0=cos(deg2rad*strct_in_vel(1,k)%radlat)
+ slat0=sin(deg2rad*strct_in_vel(1,k)%radlat)
+ thisazimuthr=(90.0_r_kind-strct_in_vel(1,k)%azim(j))*deg2rad !Storing as 90-azm to
+ ! be consistent with
+ ! read_l2bufr_mod.f90
+ rad_per_meter=one/rearth
+ rlonloc=rad_per_meter*gamma*cos(thisazimuthr)
rlatloc=rad_per_meter*gamma*sin(thisazimuthr)
-
- call invtllv(rlonloc,rlatloc,rlon0,clat0,slat0,rlonglob,rlatglob)
+
+ call invtllv(rlonloc,rlatloc,rlon0,clat0,slat0,rlonglob,rlatglob)
- thislat=rlatglob*rad2deg
+ thislat=rlatglob*rad2deg
thislon=rlonglob*rad2deg
- if(doradaroneob) then
- thislat=oneoblat
- thislon=oneoblon
- thishgt=oneobheight
- endif
+ if(doradaroneob) then
+ thislat=oneoblat
+ thislon=oneoblon
+ thishgt=oneobheight
+ endif
- if(thislon>=r360) thislon=thislon-r360
- if(thislon=r360) thislon=thislon-r360
+ if(thislonzero) errmin=min(error,errmin)
- if(abs(azm)>r400) then
- ibadazm=ibadazm+1
- cycle azms
- end if
-
- this_staid=strct_in_vel(1,k)%radid !Via equivalence in declaration, value is propagated
- ! to rstation_id used below.
-
- ! Get model terrain at radar station location
- ! If radar station is outside of grid, does not mean the
- ! radar obs are outside the grid - therefore no need to
- ! cycle azms.
-
- radar_lon=deg2rad*strct_in_vel(1,k)%radlon
- radar_lat=deg2rad*strct_in_vel(1,k)%radlat
- call tll2xy(radar_lon,radar_lat,dlon_radar,dlat_radar,outside)
- call deter_zsfc_model(dlat_radar,dlon_radar,zsges)
-
- ! Determines land surface type based on surrounding land
- ! surface types
+ if(regional .and. .not. fv3_regional) then
+ cosazm_earth=cos(thisazimuthr)
+ sinazm_earth=sin(thisazimuthr)
+ call rotate_wind_ll2xy(cosazm_earth,sinazm_earth,cosazm,sinazm,thislon,dlon,dlat)
+ azm=atan2(sinazm,cosazm)
+ else
+ azm=thisazimuthr
+ end if
+
+ !--Do limited QC from read_radar.f90--!
+ error = erradar_inflate*thiserr
+ errmax=max(error,errmax)
+ if(thiserr>zero) errmin=min(error,errmin)
+ if(abs(azm)>r400) then
+ ibadazm=ibadazm+1
+ cycle azms
+ end if
+
+ this_staid=strct_in_vel(1,k)%radid !Via equivalence in declaration, value is propagated
+ ! to rstation_id used below.
+
+ ! Get model terrain at radar station location
+ ! If radar station is outside of grid, does not mean the
+ ! radar obs are outside the grid - therefore no need to
+ ! cycle azms.
+
+ radar_lon=deg2rad*strct_in_vel(1,k)%radlon
+ radar_lat=deg2rad*strct_in_vel(1,k)%radlat
+ call tll2xy(radar_lon,radar_lat,dlon_radar,dlat_radar,outside)
+ call deter_zsfc_model(dlat_radar,dlon_radar,zsges)
+
+ ! Determines land surface type based on surrounding land
+ ! surface types
- t4dv=timeb*r60inv
-
- call deter_sfc2(thislat,thislon,t4dv,idomsfc,skint,ff10,sfcr)
-
-
+ t4dv=timeb*r60inv
+
+ call deter_sfc2(thislat,thislon,t4dv,idomsfc,skint,ff10,sfcr)
!#################### Data thinning ###################
- icntpnt=icntpnt+1
-
- if(ithin > 0)then
- if(zflag == 0)then
- klon1= int(dlon); klat1= int(dlat)
- dx = dlon-klon1; dy = dlat-klat1
- dx1 = one-dx; dy1 = one-dy
- w00=dx1*dy1; w10=dx1*dy; w01=dx*dy1; w11=dx*dy
+ icntpnt=icntpnt+1
+ if(icntpnt>maxobs) exit
+ pmot=pmot_vr
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
+
+ usage = zero
+ if(abs(icuse(ikx)) /= 1)usage=r100
- klat1=min(max(1,klat1),nlat); klon1=min(max(0,klon1),nlon)
- if (klon1==0) klon1=nlon
- klatp1=min(nlat,klat1+1); klonp1=klon1+1
- if (klonp1==nlon+1) klonp1=1
- do kk=1,nsig
- hges(kk)=w00*hgtl_full(klat1 ,klon1 ,kk) + &
- w10*hgtl_full(klatp1,klon1 ,kk) + &
- w01*hgtl_full(klat1 ,klonp1,kk) + &
- w11*hgtl_full(klatp1,klonp1,kk)
- end do
- sin2 = sin(thislat)*sin(thislat)
- termg = grav_equator * &
- ((one+somigliana*sin2)/sqrt(one-eccentricity*eccentricity*sin2))
- termr = semi_major_axis /(one + flattening + grav_ratio - &
- two*flattening*sin2)
- termrg = (termg/grav)*termr
- do kk=1,nsig
- zges(kk) = (termr*hges(kk)) / (termrg-hges(kk))
- zl_thin(kk)=zges(kk)
- end do
- endif
-
- zobs = height
-
- ntmp=ndata ! counting moved to map3gridS
- if (l4dvar) then
- timedif = zero
- else
+ if(ithin == 1)then
+ if(zflag == 0)then
+ klon1= int(dlon); klat1= int(dlat)
+ dx = dlon-klon1; dy = dlat-klat1
+ dx1 = one-dx; dy1 = one-dy
+ w00=dx1*dy1; w10=dx1*dy; w01=dx*dy1; w11=dx*dy
+
+ klat1=min(max(1,klat1),nlat); klon1=min(max(0,klon1),nlon)
+ if (klon1==0) klon1=nlon
+ klatp1=min(nlat,klat1+1); klonp1=klon1+1
+ if (klonp1==nlon+1) klonp1=1
+ do kk=1,nsig
+ hges(kk)=w00*hgtl_full(klat1 ,klon1 ,kk) + &
+ w10*hgtl_full(klatp1,klon1 ,kk) + &
+ w01*hgtl_full(klat1 ,klonp1,kk) + &
+ w11*hgtl_full(klatp1,klonp1,kk)
+ end do
+ sin2 = sin(thislat)*sin(thislat)
+ termg = grav_equator * &
+ ((one+somigliana*sin2)/sqrt(one-eccentricity*eccentricity*sin2))
+ termr = semi_major_axis /(one + flattening + grav_ratio - &
+ two*flattening*sin2)
+ termrg = (termg/grav)*termr
+ do kk=1,nsig
+ zges(kk) = (termr*hges(kk)) / (termrg-hges(kk))
+ zl_thin(kk)=zges(kk)
+ end do
+ endif
+
+ zobs = height
+
+ if (l4dvar) then
+ timedif = zero
+ else
! timedif=abs(t4dv-toff)
- timedif=abs(t4dv) !don't know about this
- endif
- crit1 = timedif/r6+half
+ timedif=abs(t4dv) !don't know about this
+ endif
+ crit1 = timedif/r6+half
- call map3grids(1,zflag,zl_thin,nlevz,thislat,thislon,&
- zobs,crit1,ndata,iout,icntpnt,iiout,luse, .false., .false.)
- maxout=max(maxout,iout)
- maxdata=max(maxdata,ndata)
-
- if (.not. luse) then
- ntdrvr_thin2=ntdrvr_thin2+1
- cycle
- endif
- if(iiout > 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+1
- endif
- isort(icntpnt)=iout
-
- else
- ndata =ndata+1
- nodata=nodata+1
- iout=ndata
- isort(icntpnt)=iout
- endif
-
- cdata_all(1,iout) = error ! wind obs error (m/s)
- cdata_all(2,iout) = dlon ! grid relative longitude
- cdata_all(3,iout) = dlat ! grid relative latitude
- cdata_all(4,iout) = thishgt ! obs absolute height (m)
- cdata_all(5,iout) = strct_in_vel(1,k)%field(i,j) ! wind obs (m/s)
- cdata_all(6,iout) = azm ! azimuth angle (radians)
- cdata_all(7,iout) = t4dv ! obs time (hour) - analysis relative
- cdata_all(8,iout) = ikx ! type
- cdata_all(9,iout) = thistiltr ! tilt angle (radians)
- cdata_all(10,iout)= this_stahgt ! station elevation (m)
- cdata_all(11,iout)= rstation_id ! station id
- cdata_all(12,iout)= icuse(ikx) ! usage parameter
- cdata_all(13,iout)= idomsfc ! dominate surface type
- cdata_all(14,iout)= skint ! skin temperature
- cdata_all(15,iout)= ff10 ! 10 meter wind factor
- cdata_all(16,iout)= sfcr ! surface roughness
- cdata_all(17,iout)=thislon*rad2deg ! earth relative longitude (degrees)
- cdata_all(18,iout)=thislat*rad2deg ! earth relative latitude (degrees)
- cdata_all(19,iout)=thisrange/1000_r_kind ! range from radar in km (used to estimate beam spread)
- cdata_all(20,iout)=zsges ! model elevation at radar site
- cdata_all(21,iout)=thiserr
- cdata_all(22,iout)=two ! Level 2 data
-
- if(doradaroneob .and. (cdata_all(5,iout) > -99_r_kind) ) exit volumes
-
- end do azms !j
- else
- num_badrange=num_badrange+1 !If outside acceptable range, increment
- end if !Range check
-
- end do gates !i
+ call map3grids_m(1,save_all,zflag,zl_thin,nlevz, &
+ thislat,thislon,zobs,crit1,ndata,&
+ luse,maxobs,rthin,.false.,.false.)
+
+ if (.not. luse) then
+ ntdrvr_thin2=ntdrvr_thin2+1
+ cycle
+ endif
+
+ else
+ ndata =ndata+1
+ endif
+ iout=ndata
+
+ cdata_all(1,iout) = error ! wind obs error (m/s)
+ cdata_all(2,iout) = dlon ! grid relative longitude
+ cdata_all(3,iout) = dlat ! grid relative latitude
+ cdata_all(4,iout) = thishgt ! obs absolute height (m)
+ cdata_all(5,iout) = strct_in_vel(1,k)%field(i,j) ! wind obs (m/s)
+ cdata_all(6,iout) = azm ! azimuth angle (radians)
+ cdata_all(7,iout) = t4dv ! obs time (hour) - analysis relative
+ cdata_all(8,iout) = ikx ! type
+ cdata_all(9,iout) = thistiltr ! tilt angle (radians)
+ cdata_all(10,iout)= this_stahgt ! station elevation (m)
+ cdata_all(11,iout)= rstation_id ! station id
+ cdata_all(12,iout)= icuse(ikx) ! usage parameter
+ cdata_all(13,iout)= idomsfc ! dominate surface type
+ cdata_all(14,iout)= skint ! skin temperature
+ cdata_all(15,iout)= ff10 ! 10 meter wind factor
+ cdata_all(16,iout)= sfcr ! surface roughness
+ cdata_all(17,iout)=thislon*rad2deg ! earth relative longitude (degrees)
+ cdata_all(18,iout)=thislat*rad2deg ! earth relative latitude (degrees)
+ cdata_all(19,iout)=thisrange/1000._r_kind ! range from radar in km (used to estimate beam spread)
+ cdata_all(20,iout)=zsges ! model elevation at radar site
+ cdata_all(21,iout)=thiserr
+ cdata_all(22,iout)=two ! Level 2 data
+
+ if(doradaroneob .and. (cdata_all(5,iout) > -99_r_kind) ) exit volumes
+ if(usage >= r100)rusage(iout)=.false.
+
+ end do azms !j
+ else
+ num_badrange=num_badrange+1 !If outside acceptable range, increment
+ end if !Range check
+
+ end do gates !i
- else
- num_badtilt=num_badtilt+1 !If outside acceptable tilts, increment
- end if !Tilt check
+ else
+ num_badtilt=num_badtilt+1 !If outside acceptable tilts, increment
+ end if !Tilt check
- end do tilts !k
+ end do tilts !k
- do k=1,nelv
- deallocate(strct_in_vel(1,k)%azim)
- deallocate(strct_in_vel(1,k)%field)
- enddo
- deallocate(strct_in_vel)
+ do k=1,nelv
+ deallocate(strct_in_vel(1,k)%azim)
+ deallocate(strct_in_vel(1,k)%field)
+ enddo
+ deallocate(strct_in_vel)
end do volumes !v
close(lunrad) !modified to do one scan at a time
@@ -625,6 +626,55 @@ subroutine read_radar_wind_ascii(nread,ndata,nodata,infile,lunout,obstype,sis,hg
endif
!end modified for thinning
+
+ nxdata=ndata
+ ndata=0
+ if(nxdata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,nxdata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' asciiradar ',trim(ioctype(ikx)),ikx,numall,&
+! numrem,numqc,numthin
+! If thinned data set quality mark to 14
+ if (ithin == 1 ) then
+ do i=1,nxdata
+ if(rthin(i))cdata_all(12,i)=101._r_kind
+ end do
+ end if
+
+! If flag to not save thinned data is set - compress data
+ if(pmot /= 1)then
+ do i=1,nxdata
+
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 2 .and. (rusage(i) .and. .not. rthin(i))) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ ndata=ndata+1
+ if(i > ndata)then
+ do k=1,maxdat
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
+ end if
+ end do
+ end if
+ end if
+ nodata=nodata+ndata
+
!---all looping done now print diagnostic output
write(6,*)'READ_RADAR_WIND_ASCII: Reached eof on radar wind ascii file'
@@ -644,12 +694,13 @@ subroutine read_radar_wind_ascii(nread,ndata,nodata,infile,lunout,obstype,sis,hg
!---------------DEALLOCATE ARRAYS-------------!
- deallocate(cdata_all)
else !fileopen
- write(6,*) 'READ_RADAR_WIND_ASCII: ERROR OPENING RADIAL VELOCITY FILE: ',trim(infile),' IOSTAT ERROR: ',ierror, ' SKIPPING...'
+ write(6,*) 'READ_RADAR_WIND_ASCII: ERROR OPENING RADIAL VELOCITY FILE: ',trim(infile),' IOSTAT ERROR: ',ierror, ' SKIPPING...'
end if fileopen
+ deallocate(cdata_all,rusage,rthin)
+
end subroutine read_radar_wind_ascii
diff --git a/src/gsi/read_rapidscat.f90 b/src/gsi/read_rapidscat.f90
index c952383df0..f1fffd43a8 100644
--- a/src/gsi/read_rapidscat.f90
+++ b/src/gsi/read_rapidscat.f90
@@ -43,16 +43,16 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
use gridmod, only: diagnostic_reg,regional,nlon,nlat,nsig,&
tll2xy,txy2ll,rotate_wind_ll2xy,rotate_wind_xy2ll,&
rlats,rlons,fv3_regional
- use qcmod, only: errormod,noiqc
- use convthin, only: make3grids,map3grids,del3grids,use_all
+ use qcmod, only: errormod
+ use convthin, only: make3grids,map3grids_m,del3grids,use_all
use constants, only: deg2rad,zero,rad2deg,one_tenth,&
tiny_r_kind,huge_r_kind,r60inv,one_tenth,&
one,two,three,four,five,half,quarter,r60inv,r10,r100,r2000
! use converr,only: etabl
- use obsmod, only: ran01dom,bmiss
+ use obsmod, only: ran01dom,bmiss,reduce_diag
use convinfo, only: nconvtype, &
icuse,ictype,icsubtype,ioctype, &
- ithin_conv,rmesh_conv,pmesh_conv
+ ithin_conv,rmesh_conv,pmesh_conv,pmot_conv
use gsi_4dvar, only: l4dvar,iwinbgn,winlen,time_4dvar,l4densvar,thin4d
use deter_sfc_mod, only: deter_sfc_type,deter_sfc2
use mpimod, only: npe
@@ -107,13 +107,12 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
integer(i_kind) ireadmg,ireadsb,iuse,mxtb,nmsgmax
integer(i_kind) i,maxobs,idomsfc,nsattype
- integer(i_kind) nc,nx,isflg,itx,nchanl
+ integer(i_kind) nc,nx,isflg,nchanl
integer(i_kind) ntb,ntmatch,ncx,ncsave,ntread
integer(i_kind) kk,klon1,klat1,klonp1,klatp1
integer(i_kind) nmind,lunin,idate,ilat,ilon,iret,k
- integer(i_kind) nreal,ithin,iout,ntmp,icount,iiout,ii
+ integer(i_kind) nreal,ithin,iout,ii
integer(i_kind) itype,iosub,ixsub,isubsub,iobsub
- integer(i_kind) lim_qm
integer(i_kind) nlevp ! vertical level for thinning
integer(i_kind) pflag
integer(i_kind) ntest,nvtest
@@ -127,7 +126,7 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
integer(i_kind),dimension(nconvtype+1) :: ntx
integer(i_kind),dimension(5):: idate5
- integer(i_kind),allocatable,dimension(:):: isort,iloc,nrep
+ integer(i_kind),allocatable,dimension(:):: nrep
integer(i_kind),allocatable,dimension(:,:)::tab
integer(i_kind) ietabl,itypex,lcount,iflag,m
@@ -135,14 +134,14 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
real(r_single),allocatable,dimension(:,:,:) :: etabl
real(r_kind) toff,t4dv
- real(r_kind) rmesh,ediff,usage,tdiff
+ real(r_kind) rmesh,ediff,tdiff
real(r_kind) u0,v0,uob,vob,dx,dy,dx1,dy1,w00,w10,w01,w11
real(r_kind) dlnpob,ppb,ppb2,qifn,qify,ee
real(r_kind) woe,dlat,dlon,dlat_earth,dlon_earth,oelev
real(r_kind) dlat_earth_deg,dlon_earth_deg
real(r_kind) cdist,disterr,disterrmax,rlon00,rlat00
real(r_kind) vdisterrmax,u00,v00,uob1,vob1
- real(r_kind) del,werrmin,obserr,ppb1
+ real(r_kind) del,werrmin,obserr,ppb1,usage
real(r_kind) tsavg,ff10,sfcr,sstime,gstime,zz
real(r_kind) crit1,timedif,xmesh,pmesh
real(r_kind),dimension(nsig):: presl
@@ -156,7 +155,11 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
real(r_double),dimension(1,1):: r_prvstg,r_sprvstg
real(r_kind),allocatable,dimension(:):: presl_thin
real(r_kind),allocatable,dimension(:,:):: cdata_all
- real(r_kind),allocatable,dimension(:,:):: cdata_out
+
+ logical,allocatable,dimension(:)::rthin,rusage
+ logical save_all
+! integer(i_kind) numthin,numqc,numrem,numall
+ integer(i_kind) nxdata,pmot
! equivalence to handle character names
equivalence(r_prvstg(1,1),c_prvstg)
@@ -213,11 +216,6 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
werrmin=one
nsattype=0
nreal=23
- if (noiqc) then
- lim_qm=8
- else
- lim_qm=4
- endif
! ** read convtype from convinfo file
! ** only read in rapidsat 296 for now **
@@ -252,7 +250,7 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
call getcount_bufr(infile,nmsgmax,mxtb)
- allocate(lmsg(nmsgmax,ntread),tab(mxtb,3),nrep(nmsgmax))
+ allocate(lmsg(nmsgmax,ntread),tab(mxtb,2),nrep(nmsgmax))
lmsg = .false.
maxobs=0
@@ -332,16 +330,13 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
end if
tab(ntb,1)=ncsave
tab(ntb,2)=nx
- tab(ntb,3)=1
lmsg(nmsg,nx) = .true.
end if
enddo loop_report
enddo msg_report
! Loop over convinfo file entries; operate on matches
- allocate(cdata_all(nreal,maxobs),isort(maxobs))
- isort = 0
- cdata_all=zero
+ allocate(cdata_all(nreal,maxobs),rusage(maxobs),rthin(maxobs))
nread=0
ntest=0
nvtest=0
@@ -352,6 +347,8 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
!! read satellite winds one type a time
! same as in the read_prepbufr.f90 file
+ rusage = .true.
+ rthin = .false.
loop_convinfo: do nx=1,ntread
use_all = .true.
ithin=0
@@ -397,6 +394,17 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
ntb = 0
nmsg = 0
+ if(nx == 1)then
+ pmot=0
+ else
+ nc=ntx(nx)
+ pmot=nint(pmot_conv(nc))
+ end if
+ if(pmot < 2 .and. reduce_diag)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
+ use_all=.true.
+
loop_msg: do while(ireadmg(lunin,subset,idate) == 0)
nmsg = nmsg+1
if(.not.lmsg(nmsg,nx)) then
@@ -547,7 +555,7 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
obserr=(one-del)*etabl(itype,k1,4)+del*etabl(itype,k2,4)
obserr=max(obserr,werrmin)
! Set usage variable
- usage = 0
+ usage = zero
iuse=icuse(nc)
if(iuse <= 0)usage=r100
@@ -584,7 +592,6 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
! Special block for data thinning - if requested
if (ithin > 0 .and. iuse >=0) then
- ntmp=ndata ! counting moved to map3gridS
! Set data quality index for thinning
if (thin4d) then
@@ -601,22 +608,16 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
end do
endif
- call map3grids(-1,pflag,presl_thin,nlevp,dlat_earth,dlon_earth,&
- ppb,crit1,ndata,iout,ntb,iiout,luse,.false.,.false.)
+ call map3grids_m(-1,save_all,pflag,presl_thin,nlevp, &
+ dlat_earth,dlon_earth,ppb,crit1,ndata,&
+ luse,maxobs,rthin,.false.,.false.)
if (.not. luse) cycle loop_readsb
- if(iiout > 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+2
- endif
- isort(ntb)=iout
else
ndata=ndata+1
- nodata=nodata+2
- iout=ndata
- isort(ntb)=iout
endif
+ iout=ndata
woe=obserr
oelev=r10
@@ -659,6 +660,7 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
cdata_all(21,iout)=zz ! terrain height at ob location
cdata_all(22,iout)=r_prvstg(1,1) ! provider name
cdata_all(23,iout)=r_sprvstg(1,1) ! subprovider name
+ if(usage >= r100)rusage(ndata)=.false.
enddo loop_readsb
@@ -675,35 +677,57 @@ subroutine read_rapidscat(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,
call closbf(lunin)
! Write header record and data to output file for further processing
- allocate(iloc(ndata))
- icount=0
- do i=1,maxobs
- if(isort(i) > 0)then
- icount=icount+1
- iloc(icount)=isort(i)
- end if
- end do
- if(ndata /= icount)then
- write(6,*) ' READ_RAPIDSCAT: mix up in read_satwnd ,ndata,icount ',ndata,icount
- call stop2(49)
- end if
- allocate(cdata_out(nreal,ndata))
- do i=1,ndata
- itx=iloc(i)
- do k=1,nreal
- cdata_out(k,i)=cdata_all(k,itx)
- end do
- end do
- deallocate(iloc,isort,cdata_all)
deallocate(etabl)
-
+ nxdata=ndata
+ ndata=0
+ if(nxdata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,nxdata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' rapid ',trim(ioctype(nc)),ictype(nc),icsubtype(nc),numall,numrem,numqc,numthin
+! If thinned data set usage
+ do i=1,nxdata
+ if(rthin(i))then
+ cdata_all(14,i)=100._r_kind
+ cdata_all(12,i)=14
+ end if
+ end do
+! If flag to not save thinned data is set - compress data
+ do i=1,nxdata
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 1) .or. &
+ (pmot == 2 .and. (rusage(i) .and. .not. rthin(i))) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ ndata=ndata+1
+ do k=1,nreal
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
+ end do
+ end if
+ nodata=nodata+ndata
+ deallocate(rusage,rthin)
- call count_obs(ndata,nreal,ilat,ilon,cdata_out,nobs)
+ call count_obs(ndata,nreal,ilat,ilon,cdata_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon
- write(lunout) cdata_out
+ write(lunout) ((cdata_all(k,i),k=1,nreal),i=1,ndata)
+
+ deallocate(cdata_all)
- deallocate(cdata_out)
-900 continue
if(diagnostic_reg .and. ntest>0) write(6,*)'READ_RAPIDSCAT: ',&
'ntest,disterrmax=',ntest,disterrmax
if(diagnostic_reg .and. nvtest>0) write(6,*)'READ_RAPIDSCAT: ',&
diff --git a/src/gsi/read_saphir.f90 b/src/gsi/read_saphir.f90
index 3547f2cf5c..06e992b03d 100644
--- a/src/gsi/read_saphir.f90
+++ b/src/gsi/read_saphir.f90
@@ -360,10 +360,10 @@ subroutine read_saphir(mype,val_tovs,ithin,isfcalc,&
! compute look angle (panglr) and check against max angle
-! panglr=(start+float(ifov-1)*step)*deg2rad
+! panglr=(start+real(ifov-1,r_kind)*step)*deg2rad
! Use this calculation for now:
step = .6660465
- panglr = (42.96 - float(ifov-1)*step)*deg2rad
+ panglr = (42.96 - real(ifov-1,r_kind)*step)*deg2rad
if(abs(lza)*rad2deg > MAX_SENSOR_ZENITH_ANGLE) then
write(6,*)'READ_SAPHIR WARNING lza error ',lza,panglr
@@ -508,7 +508,7 @@ subroutine read_saphir(mype,val_tovs,ithin,isfcalc,&
- crit1 = crit1 + rlndsea(isflg) + 10._r_kind*float(iskip) + 0.01_r_kind * abs(zz)
+ crit1 = crit1 + rlndsea(isflg) + 10._r_kind*real(iskip,r_kind) + 0.01_r_kind * abs(zz)
call checkob(dist1,crit1,itx,iuse)
if(.not. iuse)cycle ObsLoop
@@ -529,10 +529,10 @@ subroutine read_saphir(mype,val_tovs,ithin,isfcalc,&
endif
! Re-calculate look angle
-! panglr=(start+float(ifov-1)*step)*deg2rad
+! panglr=(start+real(ifov-1,r_kind)*step)*deg2rad
! Use this calculation for now:
step = .6660465
- panglr = (42.96 - float(ifov-1)*step)*deg2rad
+ panglr = (42.96 - real(ifov-1,r_kind)*step)*deg2rad
! Load selected observation into data array
diff --git a/src/gsi/read_satmar.f90 b/src/gsi/read_satmar.f90
index 673872e308..e9062a65f6 100644
--- a/src/gsi/read_satmar.f90
+++ b/src/gsi/read_satmar.f90
@@ -70,9 +70,11 @@ subroutine read_satmar (nread, ndata, nodata, &
use gridmod, only: regional, rlats,rlons,nlat,nlon,txy2ll,tll2xy, &
twodvar_regional
use satthin, only: map2tgrid,destroygrids,makegrids
- use convinfo, only: ithin_conv,rmesh_conv,nconvtype,icuse,ictype,ioctype,ctwind
- use convthin, only: make3grids,use_all,map3grids,del3grids
- use obsmod, only: bmiss,hilbert_curve
+ use convinfo, only: ithin_conv,rmesh_conv,nconvtype,icuse,ictype,ioctype,ctwind, &
+ pmot_conv
+! use convinfo, only: icsubtype
+ use convthin, only: make3grids,use_all,map3grids_m,del3grids
+ use obsmod, only: bmiss,hilbert_curve,reduce_diag
use mpimod, only: npe
implicit none
@@ -98,15 +100,14 @@ subroutine read_satmar (nread, ndata, nodata, &
real (r_kind),parameter :: r6 = 6.0_r_kind
real (r_kind),parameter :: dflt_err = 0.2_r_kind
!
- integer(i_kind) :: tot,cnt,cnt1,k,ntmp,iout,iiout
+ integer(i_kind) :: tot,cnt,cnt1,k,iout,i
integer(i_kind) :: ireadmg,ireadsb,idate
integer(i_kind) :: iRec,ierr,nc,i1,ilat,ilon,nchanl,nlevp,indsat
integer(i_kind) :: nmind, nrec
integer(i_kind) :: thisobtype_usage, iuse
! real
- real(r_kind),allocatable,dimension(:, :) :: data_all,data_out
+ real(r_kind),allocatable,dimension(:, :) :: data_all
real(r_kind),allocatable,dimension(:):: DumForThin
- integer(i_kind),allocatable,dimension(:):: isort,iloc
! real(r_kind),allocatable,dimension(: ) :: data_1d
real(r_kind) :: dlon,dlat
real(r_kind) :: tdiff,crit1,timedif,toff
@@ -171,6 +172,11 @@ subroutine read_satmar (nread, ndata, nodata, &
integer(i_kind),parameter :: howvRatMiuSigma = 3
integer(i_kind),parameter :: howvRathowvDpth = 2
real(r_kind),parameter :: howvDistm = 10000.0_r_kind
+ logical,allocatable,dimension(:)::rthin,rusage
+ logical save_all
+! integer(i_kind) numthin,numqc,numrem,numall
+ integer(i_kind) nxdata,pmot
+
!
! call init_constants_derived
lhilbert = twodvar_regional .and. hilbert_curve
@@ -203,9 +209,9 @@ subroutine read_satmar (nread, ndata, nodata, &
end if
!
! *#* Thinning *#*!
- use_all = .true.
- ithin=ithin_conv(nc)
- if (ithin > 0 ) then
+ use_all = .true.
+ ithin=ithin_conv(nc)
+ if (ithin > 0 ) then
rmesh=rmesh_conv(nc)
use_all = .false.
nlevp=1 !Dummy for using make3grids
@@ -214,7 +220,7 @@ subroutine read_satmar (nread, ndata, nodata, &
call make3grids(xmesh,nlevp)
write(6,'(A,1x,A,1x,A,I4,1x,f8.2,1x,I3,1x,I3)')myname,': ioctype(nc),ictype(nc),rmesh,nlevp,nc ',&
trim(ioctype(nc)),ictype(nc),rmesh,nlevp,nc
- endif
+ endif
!
! *#* Main - Start *#*!
open(lun11,file=trim(infile),action='read',form='unformatted', iostat=ierr)
@@ -236,13 +242,19 @@ subroutine read_satmar (nread, ndata, nodata, &
close(lun11)
!
! Allocate Arrays for all the data
- allocate (data_all (nreal, cnt),isort(cnt))
- isort = 0
+ allocate (data_all (nreal, cnt),rusage(cnt),rthin(cnt))
!
! Loop over file
open(lun11,file=trim(infile),action='read',form='unformatted')
call openbf(lun11,'IN',lun11)
call datelen(dtLen)
+ pmot=nint(pmot_conv(nc))
+ if(pmot < 2 .and. reduce_diag)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
+ rusage = .true.
+ rthin = .false.
+ use_all=.true.
!
read_msg: do while(ireadmg(lun11,subset,idate) == 0)
do i1 = 1,nosat
@@ -394,7 +406,6 @@ subroutine read_satmar (nread, ndata, nodata, &
cnt = 0
iuse=icuse(nc)
if (ithin > 0 .and. iuse >=0) then
- ntmp=ndata
if (thin4d) then
timedif = zero ! crit1=0.01_r_kind
else
@@ -402,20 +413,15 @@ subroutine read_satmar (nread, ndata, nodata, &
end if
crit1 = timedif/r6+half
!
- call map3grids(-1,0,DumForThin,nlevp,dlat_earth,dlon_earth &
- ,one ,crit1,ndata,iout,nrec,iiout,luse,.false.,.false.)
+ call map3grids_m(-1,save_all,0,DumForThin,nlevp, &
+ dlat_earth,dlon_earth,one,crit1,ndata,&
+ luse,cnt,rthin,.false.,.false.)
+
if (.not. luse) cycle
- if(iiout > 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+1
- endif
- isort(nrec)=iout
else ! - no thinnning
ndata=ndata+1
- nodata=nodata+1
- iout=ndata
- isort(nrec)=iout
endif
+ iout=ndata
!
usage = zero !- Set usage variable :: practically useless
if (howv_1d(2)<=tiny_r_kind) howv_1d(2)=dflt_err
@@ -462,44 +468,67 @@ subroutine read_satmar (nread, ndata, nodata, &
enddo read_msg
call closbf(lun11)
! Write header record and data to output file for further processing
- allocate(iloc(ndata))
- cnt1 = 0
- do i1=1,size(data_all,2)
- if(isort(i1) > 0)then
- cnt1=cnt1 + 1
- iloc(cnt1)=isort(i1)
- end if
- end do
- if(ndata /= cnt1)then
- write(6,*) myname,': ndata and icount do not match STOPPING...ndata,cnt1,cnt ',ndata,cnt1,cnt
- call stop2(50)
- end if
-!
- allocate(data_out(nreal,ndata))
- do i1=1,ndata
- iout=iloc(i1)
- do k=1,nreal
- data_out(k,i1)=data_all(k,iout)
- end do
- end do
- deallocate(iloc,isort,data_all)
-
- call count_obs(ndata,nreal,ilat,ilon,data_out,nobs)
-
- write(lunout) obstype,sis,nreal,nchanl,ilat,ilon,ndata
- write(lunout) data_out
- deallocate(data_out)
-
- if (ndata == 0) then
- write(6,*)myname,': closbf(',lun11,') no data'
- endif
- close(lun11)
!
+ nxdata=ndata
+ ndata=0
+ if(nxdata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,nxdata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' smar ',trim(ioctype(nc)),ictype(nc),icsubtype(nc),numall,numrem,numqc,numthin
+! If thinned data set usage
+ do i=1,nxdata
+ if(rthin(i))data_all(11,i)=100._r_kind
+ end do
+! If flag to not save thinned data is set - compress data
+ if(pmot /= 1)then
+ do i=1,nxdata
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 2 .and. (rusage(i) .and. .not. rthin(i))) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ ndata=ndata+1
+ if(i > ndata)then
+ do k=1,nreal
+ data_all(k,ndata)=data_all(k,i)
+ end do
+ end if
+ end if
+ end do
+ end if
+ nodata=nodata+ndata
+ end if
+
! Deallocate local arrays
if (ithin > 0 ) then
deallocate(DumForThin)
call del3grids
end if
+
+ call count_obs(ndata,nreal,ilat,ilon,data_all,nobs)
+
+ write(lunout) obstype,sis,nreal,nchanl,ilat,ilon,ndata
+ write(lunout) ((data_all(k,i1),k=1,nreal),i1=1,ndata)
+ deallocate(data_all,rusage,rthin)
+
+ if (ndata == 0) then
+ write(6,*)myname,': closbf(',lun11,') no data'
+ endif
+ close(lun11)
+!
!
end subroutine read_satmar
!
diff --git a/src/gsi/read_satwnd.f90 b/src/gsi/read_satwnd.f90
index 874483c86e..0fb9680116 100644
--- a/src/gsi/read_satwnd.f90
+++ b/src/gsi/read_satwnd.f90
@@ -18,6 +18,7 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
! 253: EUMETSAT IR winds, 254: EUMETSAT WV deep layer winds
! 257,258,259: MODIS IR,WV cloud top, WV deep layer winds
! 260: VIIR IR winds
+! 241: CIMSS enhanced AMV winds
! respectively
! For satellite subtype: 50-80 from EUMETSAT geostationary satellites(METEOSAT)
! 100-199 from JMA geostationary satellites(MTSAT)
@@ -74,11 +75,10 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
! or hilber curve downweighting
!
! 2020-05-04 wu - no rotate_wind for fv3_regional
-! 2021-07-25 Genkova - read GOES-17 AMVQ flag:8-mitigated height
-! 16-mit.target, 24-mit.target & height; write in diag
! 2021-07-25 Genkova - added code for Metop-B/C winds in new BUFR,NC005081 !
! 2022-01-20 Genkova - added missing station_id for polar winds
! 2022-01-20 Genkova - added code for Meteosat and Himawari AMVs in new BUFR
+! 2022-12-10 Bi - added code for CIMSS enhanced AMVs in new BUFR
!
!
! input argument list:
@@ -107,15 +107,15 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
tll2xy,txy2ll,rotate_wind_ll2xy,rotate_wind_xy2ll,&
rlats,rlons,twodvar_regional,wrf_nmm_regional,fv3_regional
use qcmod, only: errormod,njqc
- use convthin, only: make3grids,map3grids,map3grids_m,del3grids,use_all
- use convthin_time, only: make3grids_tm,map3grids_tm,map3grids_m_tm,del3grids_tm,use_all_tm
+ use convthin, only: make3grids,map3grids_m,del3grids,use_all
+ use convthin_time, only: make3grids_tm,map3grids_m_tm,del3grids_tm,use_all_tm
use constants, only: deg2rad,zero,rad2deg,one_tenth,&
tiny_r_kind,huge_r_kind,r60inv,one_tenth,&
one,two,three,four,five,half,quarter,r60inv,r100,r2000
use converr,only: etabl
use converr_uv,only: etabl_uv,isuble_uv,maxsub_uv
use convb_uv,only: btabl_uv
- use obsmod, only: perturb_obs,perturb_fact,ran01dom,bmiss
+ use obsmod, only: perturb_obs,perturb_fact,ran01dom,bmiss,reduce_diag
use convinfo, only: nconvtype, &
icuse,ictype,icsubtype,ioctype, &
ithin_conv,rmesh_conv,pmesh_conv,pmot_conv,ptime_conv, &
@@ -157,12 +157,11 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
real(r_kind),parameter:: r799=799.0_r_kind
real(r_kind),parameter:: r1200= 1200.0_r_kind
real(r_kind),parameter:: r10000= 10000.0_r_kind
-
-
+ real(r_double),parameter:: rmiss=10d7
! Declare local variables
logical outside,inflate_error
- logical luse,ithinp
+ logical luse,ithinp,do_qc
logical,allocatable,dimension(:,:):: lmsg ! set true when convinfo entry id found in a message
character(70) obstr_v1, obstr_v2,hdrtr_v1,hdrtr_v2
@@ -172,15 +171,15 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
character(8) c_prvstg,c_sprvstg
character(8) c_station_id,stationid
- integer(i_kind) mxtb,nmsgmax
+ integer(i_kind) mxtb,nmsgmax,qcret
integer(i_kind) ireadmg,ireadsb,iuse
integer(i_kind) i,maxobs,idomsfc,nsattype,ncount
- integer(i_kind) nc,nx,isflg,itx,j,nchanl
+ integer(i_kind) nc,nx,isflg,j,nchanl
integer(i_kind) ntb,ntmatch,ncx,ncsave,ntread
integer(i_kind) kk,klon1,klat1,klonp1,klatp1
integer(i_kind) nmind,lunin,idate,ilat,ilon,iret,k
- integer(i_kind) nreal,ithin,iout,ntmp,icount,iiout,ii
- integer(i_kind) itype,iosub,ixsub,isubsub,iobsub,itypey,ierr
+ integer(i_kind) nreal,ithin,iout,ii
+ integer(i_kind) itype,iosub,ixsub,isubsub,iobsub,itypey,ierr,ihdr9
integer(i_kind) qm
integer(i_kind) nlevp ! vertical level for thinning
integer(i_kind) pflag
@@ -192,35 +191,42 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
integer(i_kind),dimension(nconvtype+1) :: ntx
integer(i_kind),dimension(5):: idate5
- integer(i_kind),allocatable,dimension(:):: nrep,isort,iloc
+ integer(i_kind),allocatable,dimension(:):: nrep,istab
integer(i_kind),allocatable,dimension(:,:):: tab
+ integer(i_kind) :: icnt(1000)
- integer(i_kind) ntime,itime
+ integer(i_kind) ntime,itime,istype
real(r_kind) toff,t4dv
- real(r_kind) rmesh,ediff,usage,tdiff
+ real(r_kind) rmesh,ediff,tdiff
real(r_kind) u0,v0,uob,vob,dx,dy,dx1,dy1,w00,w10,w01,w11
- real(r_kind) dlnpob,ppb,ppb2,qifn,qify,ee,ree,pct1,experr_norm
+ real(r_kind) dlnpob,ppb,qifn,qify,ee,ree,pct1,experr_norm
real(r_kind) woe,dlat,dlon,dlat_earth,dlon_earth
real(r_kind) dlat_earth_deg,dlon_earth_deg
real(r_kind) cdist,disterr,disterrmax,rlon00,rlat00
- real(r_kind) vdisterrmax,u00,v00,uob1,vob1
- real(r_kind) del,werrmin,obserr,ppb1,var_jb,wjbmin,wjbmax
+ real(r_kind) vdisterrmax,u00,v00
+ real(r_kind) del,werrmin,obserr,var_jb,wjbmin,wjbmax
+! real(r_kind) ppb1,ppb2,uob1,vob1
real(r_kind) tsavg,ff10,sfcr,sstime,gstime,zz
- real(r_kind) crit1,timedif,xmesh,pmesh,pmot,ptime
+ real(r_kind) crit1,timedif,xmesh,pmesh,ptime
real(r_kind),dimension(nsig):: presl
real(r_double),dimension(13):: hdrdat
- real(r_double),dimension(5):: obsdat
- real(r_double),dimension(2) :: hdrdat_test
- real(r_double),dimension(3,5) :: heightdat
- real(r_double),dimension(6,4) :: derdwdat
+ real(r_double),dimension(4):: obsdat
+ real(r_double),dimension(2) :: hdrdat_test,hdrdat_005099
+! real(r_double),dimension(3,5) :: heightdat
+! real(r_double),dimension(6,4) :: derdwdat
real(r_double),dimension(3,12) :: qcdat
real(r_double),dimension(1,1):: r_prvstg,r_sprvstg
real(r_kind),allocatable,dimension(:):: presl_thin
- real(r_kind),allocatable,dimension(:):: rusage
- real(r_kind),allocatable,dimension(:,:):: cdata_all,cdata_out
+ real(r_kind),allocatable,dimension(:,:):: cdata_all
+
+ logical,allocatable,dimension(:)::rthin,rusage
+ logical save_all
+ !integer(i_kind) numthin,numqc,numrem,numall
+ integer(i_kind) nxdata,pmot
+
! GOES-16 new BUFR related variables
real(r_double) :: rep_array
@@ -242,8 +248,8 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
data hdrtr_v2 /'SAID CLATH CLONH YEAR MNTH DAYS HOUR MINU SWCM SAZA OGCE SCCF SWQM'/ ! OGCE replaces GCLONG, OGCE exists in old and new BUFR
! SWQM doesn't exist in the new BUFR, so qm is initialized to '2' manually
- data obstr_v1 /'HAMD PRLC WDIR WSPD AMVQ'/
- data obstr_v2 /'EHAM PRLC WDIR WSPD AMVQ'/
+ data obstr_v1 /'HAMD PRLC WDIR WSPD'/
+ data obstr_v2 /'EHAM PRLC WDIR WSPD'/
! data heightr/'MDPT '/
! data derdwtr/'TWIND'/
data qcstr /' OGCE GNAP PCCF'/
@@ -265,21 +271,22 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
wjbmax=5.0_r_kind
pflag=0
var_jb=zero
+ icnt=0
! allocate(etabl(302,33,6)) ! add 2 ObsErr profiles for GOES-R IR(itype=301) and WV(itype=300) (not used yet, 2015-07-08, Genkova)
! Set lower limits for observation errors
werrmin=one
nsattype=0
- nreal=27
+ nreal=34
if(perturb_obs ) nreal=nreal+2
ntread=1
ntmatch=0
ntx(ntread)=0
ntxall=0
do nc=1,nconvtype
- if( (trim(ioctype(nc)) == 'uv' .or. trim(ioctype(nc)) == 'wspd10m' .or. trim(ioctype(nc)) == 'uwnd10m' .or. trim(ioctype(nc)) == 'vwnd10m') .and. ictype(nc) >=240 &
- .and. ictype(nc) <=265) then
+ if((trim(ioctype(nc)) == 'uv' .or. trim(ioctype(nc)) == 'wspd10m' .or. trim(ioctype(nc)) == 'uwnd10m' .or. &
+ trim(ioctype(nc)) == 'vwnd10m') .and. ictype(nc) >=240 .and. ictype(nc) <=265) then
ntmatch=ntmatch+1
ntxall(ntmatch)=nc
ithin=ithin_conv(nc)
@@ -289,6 +296,7 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
end if
end if
end do
+
if(ntmatch == 0)then
write(6,*) ' READ_SATWND: no matching obstype found in obsinfo ',obstype
return
@@ -300,12 +308,12 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
call getcount_bufr(infile,nmsgmax,mxtb)
- allocate(lmsg(nmsgmax,ntread),tab(mxtb,3),nrep(nmsgmax))
-
+ allocate(lmsg(nmsgmax,ntread),istab(nmsgmax),tab(mxtb,3),nrep(nmsgmax))
lmsg = .false.
maxobs=0
tab=0
+ istab=0
nmsg=0
nrep=0
ntb =0
@@ -316,6 +324,7 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
msg_report: do while (ireadmg(lunin,subset,idate) == 0)
! if(trim(subset) == 'NC005012') cycle msg_report
+ istype=0
! Time offset
if(nmsg == 0) call time_4dvar(idate,toff)
nmsg=nmsg+1
@@ -323,15 +332,85 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
write(6,*)'READ_SATWND: messages exceed maximum ',nmsgmax
call stop2(49)
endif
+ if(trim(subset) == 'NC005064' .or. trim(subset) == 'NC005065' .or. &
+ trim(subset) == 'NC005066') then
+! EUMETSAT satellite IDS
+ istype=1
+ else if(trim(subset) == 'NC005067' .or. trim(subset) == 'NC005068' .or.&
+ trim(subset) == 'NC005069') then ! read new EUM BURF
+! EUMETSAT new BUFR satellite IDS
+ istype=2
+ else if(trim(subset) == 'NC005041' .or. trim(subset) == 'NC005042' .or. &
+ trim(subset) == 'NC005043') then
+! JMA satellite IDS
+ istype=3
+ else if(trim(subset) == 'NC005044' .or. trim(subset) == 'NC005045' .or. &
+ trim(subset) == 'NC005046') then
+! JMA satellite IDS
+ istype=4
+
+ else if(trim(subset) == 'NC005047' .or. trim(subset) == 'NC005048' .or.&
+ trim(subset) == 'NC005049') then ! read new Him-8 BURF
+! new HIM-8 BUFR
+ istype=5
+ else if(trim(subset) == 'NC005001' .or. trim(subset) == 'NC005002' .or. &
+ trim(subset) == 'NC005003' ) then
+! NESDIS BUFR
+ istype=6
+ else if(trim(subset) == 'NC005010' .or. trim(subset) == 'NC005011' .or. &
+ trim(subset) == 'NC005012' ) then
+! NESDIS BUFR
+ istype=7
+ else if(trim(subset) == 'NC005070' .or. trim(subset) == 'NC005071' ) then
+! NASA AQUA and Terra winds
+ istype=8
+ else if( trim(subset) == 'NC005080') then
+! EUMETSAT and NOAA polar winds
+ istype=9
+ else if( trim(subset) == 'NC005081') then
+! EUMETSAT polar winds
+ istype=10
+ else if( trim(subset) == 'NC005019') then
+! GOES shortwave winds
+ istype=11
+ else if( trim(subset) == 'NC005072') then
+! LEOGEO (LeoGeo) winds
+ istype=12
+ else if( trim(subset) == 'NC005090') then
+! VIIRS winds
+ istype=13
+ else if(trim(subset) == 'NC005091') then
+! VIIRS N-20 with new sequence
+ istype=14
+ else if(trim(subset) == 'NC005030') then
+! GOES-R IR LW winds
+ istype=15
+ else if(trim(subset) == 'NC005039') then
+! GOES-R IR SW winds
+ istype=16
+ else if(trim(subset) == 'NC005032') then
+! GOES-R VIS winds
+ istype=17
+ else if(trim(subset) == 'NC005034') then
+! GOES-R WV cloud top
+ istype=18
+ else if(trim(subset) == 'NC005031') then
+! GOES-R WV clear sky/deep layer
+ istype=19
+ else if(trim(subset) == 'NC005099') then
+ istype=20
+ else
+! write(6,*) ' subset not found ',trim(subset),nmsg
+ end if
+ istab(nmsg)=istype
loop_report: do while (ireadsb(lunin) == 0)
ntb = ntb+1
- maxobs=maxobs+1
nrep(nmsg)=nrep(nmsg)+1
+ maxobs=maxobs+1
if (ntb>mxtb) then
write(6,*)'READ_SATWND: reports exceed maximum ',mxtb
call stop2(49)
endif
-
call ufbint(lunin,hdrdat,13,1,iret,hdrtr_v1)
! SWQM doesn't exist for GOES-R/new BUFR/ hence hdrdat(13)=MISSING.
@@ -340,165 +419,195 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
iobsub=0
itype=-1
iobsub=int(hdrdat(1))
- if(trim(subset) == 'NC005064' .or. trim(subset) == 'NC005065' .or. &
- trim(subset) == 'NC005066') then
+ ihdr9=nint(hdrdat(9))
+
+ if(istype == 1) then
if( hdrdat(1) = r50) then !the range of EUMETSAT satellite IDS
- if(hdrdat(9) == one) then ! IR winds
+ if(ihdr9 == 1) then ! IR winds
itype=253
- else if(hdrdat(9) == two) then ! visible winds
+ else if(ihdr9 == 2) then ! visible winds
itype=243
- else if(hdrdat(9) == three) then ! WV cloud top
+ else if(ihdr9 == 3) then ! WV cloud top
itype=254
- else if(hdrdat(9) >= four) then ! WV deep layer, monitored
+ else if(ihdr9 >= 4) then ! WV deep layer, monitored
itype=254
endif
endif
- else if(trim(subset) == 'NC005067' .or. trim(subset) == 'NC005068' .or.&
- trim(subset) == 'NC005069') then ! read new EUM BURF
+
+ else if(istype == 2) then ! read new EUM BURF
if( hdrdat(1) = r50) then !the range of EUMETSAT satellite IDS
- if(hdrdat(9) == one) then ! IR winds
+ if(ihdr9 == 1) then ! IR winds
itype=253
- else if(hdrdat(9) == two) then ! visible winds
+ else if(ihdr9 == 2) then ! visible winds
itype=243
- else if(hdrdat(9) == three) then ! WV cloud top
+ else if(ihdr9 == 3) then ! WV cloud top
itype=254
- else if(hdrdat(9) >= four) then ! WV deep layer, monitored
+ else if(ihdr9 >= 4) then ! WV deep layer, monitored
itype=254
endif
endif
- else if(trim(subset) == 'NC005044' .or. trim(subset) == 'NC005045' .or. &
- trim(subset) == 'NC005046') then
+
+ else if(istype == 3) then
if( hdrdat(1) >=r100 .and. hdrdat(1) <=r199 ) then ! the range of JMA satellite IDS
- if(hdrdat(9) == one) then ! IR winds
+ if(ihdr9 == 1) then ! IR winds
itype=252
- else if(hdrdat(9) == two) then ! visible winds
+ else if(ihdr9 == 2) then ! visible winds
itype=242
- else if(hdrdat(9) == three) then ! WV cloud top
+ else if(ihdr9 == 3) then ! WV cloud top
itype=250
- else if(hdrdat(9) >= four) then ! WV deep layer,monitored
+ else if(ihdr9 >= 4) then ! WV deep layer,monitored
itype=250
endif
endif
- else if(trim(subset) == 'NC005047' .or. trim(subset) == 'NC005048' .or.&
- trim(subset) == 'NC005049') then ! read new Him-8 BURF
+
+ else if(istype == 4) then
if( hdrdat(1) >=r100 .and. hdrdat(1) <=r199 ) then ! the range of JMA satellite IDS
- if(hdrdat(9) == one) then ! IR winds
+ if(ihdr9 == 1) then ! IR winds
itype=252
- else if(hdrdat(9) == two) then ! visible winds
+ else if(ihdr9 == 2) then ! visible winds
itype=242
- else if(hdrdat(9) == three) then ! WV cloud top
+ else if(ihdr9 == 3) then ! WV cloud top
itype=250
- else if(hdrdat(9) >= four) then ! WV deep layer, monitored
+ else if(ihdr9 >= 4) then ! WV deep layer,monitored
itype=250
endif
endif
- else if(trim(subset) == 'NC005010' .or. trim(subset) == 'NC005011' .or. &
- trim(subset) == 'NC005012' ) then
+
+ else if(istype == 5) then ! read new Him-8 BURF
+ if( hdrdat(1) >=r100 .and. hdrdat(1) <=r199 ) then ! the range of JMA satellite IDS
+ if(ihdr9 == 1) then ! IR winds
+ itype=252
+ else if(ihdr9 == 2) then ! visible winds
+ itype=242
+ else if(ihdr9 == 3) then ! WV cloud top
+ itype=250
+ else if(ihdr9 >= 4) then ! WV deep layer, monitored
+ itype=250
+ endif
+ endif
+
+ else if(istype == 6) then
+ if( hdrdat(1) >=r250 .and. hdrdat(1) <=r299 ) then ! the range of NESDIS satellite IDS
+ if(ihdr9 == 1) then ! IR winds
+ if(hdrdat(12) <50000000000000.0_r_kind) then
+ itype=245
+ else
+ itype=240 ! short wave IR winds
+ endif
+ else if(ihdr9 == 2 ) then ! visible winds
+ itype=251
+ else if(ihdr9 == 3 ) then ! WV cloud top
+ itype=246
+ else if(ihdr9 >= 4 ) then ! WV deep layer,monitored
+ itype=247
+ endif
+ endif
+
+ else if(istype == 7) then
if( hdrdat(1) >=r250 .and. hdrdat(1) <=r299 ) then ! the range of NESDIS satellite IDS
- if(hdrdat(9) == one) then ! IR winds
+ if(ihdr9 == 1) then ! IR winds
if(hdrdat(12) <50000000000000.0_r_kind) then
itype=245
else
- itype=240 ! short wave IR winds
+ itype=240 ! short wave IR winds
endif
- else if(hdrdat(9) == two ) then ! visible winds
+ else if(ihdr9 == 2 ) then ! visible winds
itype=251
- else if(hdrdat(9) == three ) then ! WV cloud top
+ else if(ihdr9 == 3 ) then ! WV cloud top
itype=246
- else if(hdrdat(9) >= four ) then ! WV deep layer,monitored
+ else if(ihdr9 >= 4 ) then ! WV deep layer,monitored
itype=247
endif
endif
- else if(trim(subset) == 'NC005070' .or. trim(subset) == 'NC005071' ) then
+
+ else if(istype == 8) then
if( hdrdat(1) >=r700 .and. hdrdat(1) <= r799 ) then ! the range of NASA Terra and Aqua satellite IDs
- if(hdrdat(9) == one) then ! IR winds
+ if(ihdr9 == 1) then ! IR winds
itype=257
- else if(hdrdat(9) == three) then ! WV cloud top
+ else if(ihdr9 == 3) then ! WV cloud top
itype=258
- else if(hdrdat(9) >= four) then ! WV deep layer
+ else if(ihdr9 >= 4) then ! WV deep layer
itype=259
endif
endif
- else if( trim(subset) == 'NC005080') then
+ else if(istype == 9) then
if( hdrdat(1) <10.0_r_kind .or. (hdrdat(1) >= 200.0_r_kind .and. &
hdrdat(1) <=223.0_r_kind) ) then ! the range of EUMETSAT and NOAA polar orbit satellite IDs
- if(hdrdat(9) == one) then ! IR winds
+ if(ihdr9 == 1) then ! IR winds
itype=244
else
write(6,*) 'READ_SATWND: wrong derived method value'
endif
endif
- else if( trim(subset) == 'NC005081') then
+ else if(istype == 10) then
if( hdrdat(1) <10.0_r_kind ) then ! the range of EUMETSAT polar orbit satellite IDs new BUFR
- if(hdrdat(9) == one) then ! IR winds
+ if(ihdr9 == 1) then ! IR winds
itype=244
else
write(6,*) 'READ_SATWND: wrong derived method value'
endif
endif
- else if( trim(subset) == 'NC005019') then ! GOES shortwave winds
+
+ else if(istype == 11) then ! GOES shortwave winds
if(hdrdat(1) >=r250 .and. hdrdat(1) <=r299 ) then ! The range of NESDIS satellite IDS
- if(hdrdat(9) == one) then ! short wave IR winds
+ if(ihdr9 == 1) then ! short wave IR winds
itype=240
endif
endif
- else if( trim(subset) == 'NC005072') then ! LEOGEO (LeoGeo) winds
+ else if(istype == 12) then ! LEOGEO (LeoGeo) winds
if(hdrdat(1) == 854 ) then ! LeoGeo satellite ID
- if(hdrdat(9) == one) then ! LEOGEO IRwinds
+ if(ihdr9 == 1) then ! LEOGEO IRwinds
itype=255
endif
endif
- else if( trim(subset) == 'NC005090') then ! VIIRS winds
+ else if(istype == 13) then ! VIIRS winds
if(hdrdat(1) >=r200 .and. hdrdat(1) <=r250 ) then ! The range of satellite IDS
- if(hdrdat(9) == one) then ! VIIRS IR winds
+ if(ihdr9 == 1) then ! VIIRS IR winds
itype=260
endif
endif
- else if(trim(subset) == 'NC005091') then ! VIIRS N-20 with new sequence
-! Commented out, because we need clarification for SWCM/hdrdat(9) from Yi Song
+ else if(istype == 14) then ! VIIRS N-20 with new sequence
+! Commented out, because we need clarification for SWCM/ihdr9 from Yi Song
! NOTE: Once it is confirmed that SWCM values are sensible, apply this logic and
! replace lines 685-702
- ! if(hdrdat(9) == one) then ! VIIRS IR
+ ! if(ihdr9 == 1) then ! VIIRS IR
! winds
! itype=260
! endif
!Temporary solution replacing the commented code above
- if(trim(subset) == 'NC005091') then ! IR LW winds
- itype=260
- endif
+ itype=260
!GOES-R section of the 'if' statement over 'subsets'
- else if(trim(subset) == 'NC005030' .or. trim(subset) == 'NC005031' .or. trim(subset) == 'NC005032' .or. &
- trim(subset) == 'NC005034' .or. trim(subset) == 'NC005039') then
-! Commented out, because we need clarification for SWCM/hdrdat(9) from Yi Song
+! Commented out, because we need clarification for SWCM/ihdr9 from Yi Song
! NOTE: Once it is confirmed that SWCM values are sensible, apply this logic and replace lines 685-702
-! if(hdrdat(9) == one) then
+! if(ihdr9 == 1) then
! if(hdrdat(12) <50000000000000.0_r_kind) then
! itype=245 ! GOES-R IR(LW) winds
! else
! itype=240 ! GOES-R IR(SW) winds
! endif
-! else if(hdrdat(9) == two ) then
+! else if(ihdr9 == 2 ) then
! itype=251 ! GOES-R VIS winds
-! else if(hdrdat(9) == three ) then
+! else if(ihdr9 == 3 ) then
! itype=246 ! GOES-R CT WV winds
-! else if(hdrdat(9) >= four ) then
+! else if(ihdr9 >= 4 ) then
! itype=247 ! GOES-R CS WV winds
! endif
!Temporary solution replacing the commented code above
- if(trim(subset) == 'NC005030') then ! IR LW winds
- itype=245
- else if(trim(subset) == 'NC005039') then ! IR SW winds
- itype=240
- else if(trim(subset) == 'NC005032') then ! VIS winds
- itype=251
- else if(trim(subset) == 'NC005034') then ! WV cloud top
- itype=246
- else if(trim(subset) == 'NC005031') then ! WV clear sky/deep layer
- itype=247
- endif
+ else if(istype == 15) then ! IR LW winds
+ itype=245
+ else if(istype == 16) then ! IR SW winds
+ itype=240
+ else if(istype == 17) then ! VIS winds
+ itype=251
+ else if(istype == 18) then ! WV cloud top
+ itype=246
+ else if(istype == 19) then ! WV clear sky/deep layer
+ itype=247
+ else if(istype == 20) then
+ itype=241
else ! wind is not recognised and itype is not assigned
cycle loop_report
endif
@@ -532,7 +641,6 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
! Save information for next read
if(ncsave /= 0) then
- maxobs=maxobs+1
nx=1
if(ithin_conv(ncsave) > 0 .and. ithin_conv(ncsave) <5)then
do ii=2,ntread
@@ -541,38 +649,38 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
end if
tab(ntb,1)=ncsave
tab(ntb,2)=nx
- tab(ntb,3)=1
+ tab(ntb,3)=itype
lmsg(nmsg,nx) = .true.
end if
enddo loop_report
enddo msg_report
-
- allocate(cdata_all(nreal,maxobs),isort(maxobs),rusage(maxobs))
- isort = 0
- cdata_all=zero
nread=0
ntest=0
nvtest=0
nchanl=0
ilon=2
ilat=3
- rusage=101.0_r_kind
-
-! Open, then read date from bufr data
-!! read satellite winds one type a time
+ allocate(cdata_all(nreal,maxobs),rthin(maxobs),rusage(maxobs))
+ rusage = .true.
+ rthin = .false.
loop_convinfo: do nx=1,ntread
+
+ ! set parameters for processing the next satwind type
use_all = .true.
use_all_tm = .true.
ithin=0
+! Default for non thinned data is save all
+ pmot=0
+
if(nx >1) then
nc=ntx(nx)
ithin=ithin_conv(nc)
+ pmot = pmot_conv(nc)
if (ithin > 0 .and. ithin <5) then
rmesh=rmesh_conv(nc)
pmesh=pmesh_conv(nc)
- pmot=pmot_conv(nc)
ptime=ptime_conv(nc)
if(pmesh > zero) then
pflag=1
@@ -598,14 +706,18 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
enddo
endif
endif
- write(6,'(a52,a16,I5,f10.2,2i5,f10.2,i5,2f10.2)') &
+ write(6,'(a52,a16,I5,f10.2,2i5,f10.2,i5,i5,f10.2)') &
' READ_SATWND: ictype(nc),rmesh,pflag,nlevp,pmesh,nc ', &
ioctype(nc),ictype(nc),rmesh,pflag,nlevp,pmesh,nc,pmot,ptime
endif
endif
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
+
+ ! Open and read the file once for each satwnd type
call closbf(lunin)
- close(lunin)
open(lunin,file=trim(infile),form='unformatted')
call openbf(lunin,'IN',lunin)
call datelen(10)
@@ -614,54 +726,59 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
ncount=0
loop_msg: do while(IREADMG(lunin,subset,idate) == 0)
nmsg = nmsg+1
- if(.not.lmsg(nmsg,nx)) then
+ istype = istab(nmsg)
+ if(.not.lmsg(nmsg,nx) .or. istype == 3 .or. istype == 6) then
+! currently istypes 3 and 6 not used. If adding needs to be deleted from above line
+! as well as below.
ntb=ntb+nrep(nmsg)
cycle loop_msg ! no useable reports this mesage, skip ahead report count
end if
loop_readsb: do while(ireadsb(lunin) == 0)
ntb = ntb+1
- nc=tab(ntb,1)
+ nc = tab(ntb,1)
if(nc <= 0 .or. tab(ntb,2) /= nx) cycle loop_readsb
+ itype = tab(ntb,3)
+ if(itype <= 0) cycle loop_readsb
hdrdat=bmiss
obsdat=bmiss
- heightdat=bmiss
- derdwdat=bmiss
+! heightdat=bmiss
+! derdwdat=bmiss
qcdat=bmiss
- iobsub=0
- itype=-1
uob=bmiss
vob=bmiss
ppb=bmiss
- ppb1=bmiss
- ppb2=bmiss
- uob1=bmiss
- vob1=bmiss
+! ppb1=bmiss
+! ppb2=bmiss
+! uob1=bmiss
+! vob1=bmiss
ee=r110
qifn=r110
qify=r110
-! Test for BUFR version using lat/lon mnemonics
+ ! test for BUFR version using lat/lon mnemonics
call ufbint(lunin,hdrdat_test,2,1,iret, 'CLAT CLON')
if ( hdrdat_test(1) > 100000000.0_r_kind .and. hdrdat_test(2) > 100000000.0_r_kind ) then
call ufbint(lunin,hdrdat,13,1,iret,hdrtr_v2)
- call ufbint(lunin,obsdat,5,1,iret,obstr_v2)
+ call ufbint(lunin,obsdat,4,1,iret,obstr_v2)
else
call ufbint(lunin,hdrdat,13,1,iret,hdrtr_v1)
- call ufbint(lunin,obsdat,5,1,iret,obstr_v1)
+ call ufbint(lunin,obsdat,4,1,iret,obstr_v1)
endif
+ ! reject data with missing pressure or wind
ppb=obsdat(2)
- if (ppb > 100000000.0_r_kind .or. &
- hdrdat(3) >100000000.0_r_kind .or. &
- obsdat(4) > 100000000.0_r_kind) cycle loop_readsb
- if(ppb >r10000) ppb=ppb/r100
- if (ppb rmiss .or. hdrdat(3)>rmiss .or. obsdat(4)>rmiss) cycle loop_readsb
+ if(ppb>r10000) ppb=ppb/r100 ! ppb<10000 may indicate data reported in daPa or hPa
+
+ ! reject date above 125mb (or 850 for regional)
+ if ((twodvar_regional .and. ppb twind) cycle loop_readsb
endif
- iosub=0
+ ! reject data with bad lat/lon
if(abs(hdrdat(2)) >r90 ) cycle loop_readsb
if( hdrdat(3) r360) cycle loop_readsb
qm=2
iobsub=int(hdrdat(1))
+ ihdr9=nint(hdrdat(9))
write(stationid,'(i3)') iobsub
- ! assign types and get quality info : start
- if(trim(subset) == 'NC005064' .or. trim(subset) == 'NC005065' .or. &
- trim(subset) == 'NC005066') then
- if( hdrdat(1) = r50) then ! the range of EUMETSAT satellite IDs
- c_prvstg='EUMETSAT'
- if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
- if(hdrdat(9) == one) then ! IR winds
- itype=253
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- else if(hdrdat(9) == two) then ! visible winds
- itype=243
- c_station_id='VI'//stationid
- c_sprvstg='VI'
- else if(hdrdat(9) == three) then ! WV cloud top, try to assimilate
- itype=254
- c_station_id='WV'//stationid
- c_sprvstg='WV'
- else if(hdrdat(9) >= four) then ! WV deep layer,monitoring
- itype=254
- qm=9 ! quality mark as 9, means the observation error needed to be set
- c_station_id='WV'//stationid
- c_sprvstg='WV'
- endif
+ ! counter for satwnd types
+ !if(itype>=240.and.itype<=279) icnt(itype)=icnt(itype)+1
+
+ ! test for QCSTR or MANDATORY QC - if not skip over the extra blocks
+ call ufbrep(lunin,qcdat,3,12,qcret,qcstr)
+ do_qc = subset(1:7)=='NC00503'.and.nint(hdrdat(1))>=270
+ do_qc = do_qc.or.subset(1:7)=='NC00501'
+ do_qc = do_qc.or.subset=='NC005081'.or.subset=='NC005091'
+ do_qc = do_qc.or.qcret>0
+
+ ! assign types and get quality info: start
+
+ if(.not.do_qc) then
+ continue
+ else if(istype == 1) then
+ if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
+ c_prvstg='EUMETSAT'
+ if(ihdr9 == 1) then ! IR winds
+! itype=253
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ else if(ihdr9 == 2) then ! visible winds
+! itype=243
+ c_station_id='VI'//stationid
+ c_sprvstg='VI'
+ else if(ihdr9 == 3) then ! WV cloud top, try to assimilate
+! itype=254
+ c_station_id='WV'//stationid
+ c_sprvstg='WV'
+ else if(ihdr9 >= 4) then ! WV deep layer,monitoring
+! itype=254
+ qm=9 ! quality mark as 9, means the observation error needed to be set
+ c_station_id='WV'//stationid
+ c_sprvstg='WV'
+ endif
! get quality information
- call ufbrep(lunin,qcdat,3,12,iret,qcstr)
- do j=4,9
- if( qify r105) then
- qify=qcdat(3,j)
- else if(qcdat(2,j) == two .and. qifn >r105) then
- qifn=qcdat(3,j)
- else if(qcdat(2,j) == three .and. ee >r105) then
- ee=qcdat(3,j)
- endif
+ do j=4,9
+ if( qify r105) then
+ qify=qcdat(3,j)
+ else if(qcdat(2,j) == two .and. qifn >r105) then
+ qifn=qcdat(3,j)
+ else if(qcdat(2,j) == three .and. ee >r105) then
+ ee=qcdat(3,j)
endif
- enddo
- if(qifn <85.0_r_kind ) then ! qifn, QI without forecast
- qm=15
endif
+ enddo
+ if(qifn <85.0_r_kind ) then ! qifn, QI without forecast
+ qm=15
+ endif
+! Extra block for new EUMETSAT BUFR: Start
+ else if(istype == 2)then ! new EUM BUFR
+ if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
+ c_prvstg='EUMETSAT'
+ if(ihdr9 == 1) then ! IR winds
+! itype=253
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ else if(ihdr9 == 2) then ! visible winds
+! itype=243
+ c_station_id='VI'//stationid
+ c_sprvstg='VI'
+ else if(ihdr9 == 3) then ! WV cloud top, try to assimilate
+! itype=254
+ c_station_id='WV'//stationid
+ c_sprvstg='WV'
+ else if(ihdr9 >= 4) then ! WV deep layer,monitoring
+! itype=254
+ qm=9 ! quality mark as 9, means the observation error needed to be set
+ c_station_id='WV'//stationid
+ c_sprvstg='WV'
+ endif
+! get quality information THIS SECTION NEEDS TO BE TESTED!!!
+ call ufbint(lunin,rep_array,1,1,iret, '{AMVIVR}')
+ irep_array = max(1,int(rep_array))
+ allocate( amvivr(2,irep_array))
+ call ufbrep(lunin,amvivr,2,irep_array,iret, 'TCOV CVWD')
+ pct1 = amvivr(2,1) ! use of pct1 (a new variable in the BUFR) is introduced by Nebuda/Genkova
+ deallocate( amvivr )
+ call ufbseq(lunin,amvqic,2,4,iret, 'AMVQIC') ! AMVQIC:: GNAPS PCCF
+ qifn = amvqic(2,2) ! QI w/ fcst does not exist in this BUFR
+ ee = amvqic(2,4) ! NOTE: GOES-R's ee is in [m/s]
+ if(qifn <85.0_r_kind ) then ! qifn, QI without forecast
+ qm=15
+ endif
+! Extra block for new EUMETSAT BUFR: End
+ else if(istype == 4) then ! JMA
+ if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
+ c_prvstg='JMA'
+ if(ihdr9 == 1) then ! IR winds
+! itype=252
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ else if(ihdr9 == 2) then ! visible winds
+! itype=242
+ c_station_id='VI'//stationid
+ c_sprvstg='VI'
+ else if(ihdr9 == 3) then ! WV cloud top
+! itype=250
+ c_station_id='WV'//stationid
+ c_sprvstg='WV'
+ else if(ihdr9 >= 4) then ! WV deep layer,as monitoring
+! itype=250
+ qm=9
+ c_station_id='WV'//stationid
+ c_sprvstg='WV'
endif
- else if(trim(subset) == 'NC005044' .or. trim(subset) == 'NC005045' .or. & ! JMA
- trim(subset) == 'NC005046') then
- if(hdrdat(1) >=r100 .and. hdrdat(1) <=r199 ) then ! the range of JMA satellite IDS
- c_prvstg='JMA'
- if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
- if(hdrdat(9) == one) then ! IR winds
- itype=252
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- else if(hdrdat(9) == two) then ! visible winds
- itype=242
- c_station_id='VI'//stationid
- c_sprvstg='VI'
- else if(hdrdat(9) == three) then ! WV cloud top
- itype=250
- c_station_id='WV'//stationid
- c_sprvstg='WV'
- else if(hdrdat(9) >=four) then ! WV deep layer,as monitoring
- itype=250
- qm=9
- c_station_id='WV'//stationid
- c_sprvstg='WV'
- endif
! get quality information
- call ufbrep(lunin,qcdat,3,12,iret,qcstr)
- do j=4,9
- if( qify <=r105 .and. qifn r105 ) then
- qify=qcdat(3,j)
- else if(qcdat(2,j) == 102.0_r_kind .and. qifn >r105 ) then
- qifn=qcdat(3,j)
- else if(qcdat(2,j) == 103.0_r_kind .and. ee >r105) then
- ee=qcdat(3,j)
- endif
+ do j=4,9
+ if( qify <=r105 .and. qifn r105 ) then
+ qify=qcdat(3,j)
+ else if(qcdat(2,j) == 102.0_r_kind .and. qifn >r105 ) then
+ qifn=qcdat(3,j)
+ else if(qcdat(2,j) == 103.0_r_kind .and. ee >r105) then
+ ee=qcdat(3,j)
endif
- enddo
-
- if(qifn <85.0_r_kind ) then ! qifn: QI value without forecast
- qm=15
endif
+ enddo
+
+ if(qifn <85.0_r_kind ) then ! qifn: QI value without forecast
+ qm=15
endif
- else if(trim(subset) == 'NC005010' .or. trim(subset) == 'NC005011' .or. & ! NESDIS GOES
- trim(subset) == 'NC005012' ) then
- if(hdrdat(1) >=r250 .and. hdrdat(1) <=r299 ) then ! the range of NESDIS satellite IDS
- c_prvstg='NESDIS'
- if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
- if(hdrdat(9) == one) then ! IR winds
- if(hdrdat(12) <50000000000000.0_r_kind) then ! for channel 4
- itype=245
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- else
- itype=240 ! short wave winds
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- endif
- else if(hdrdat(9) == two ) then ! visible winds
- itype=251
- c_station_id='VI'//stationid
- c_sprvstg='VI'
- else if(hdrdat(9) == three) then ! WV cloud top
- itype=246
- c_station_id='WV'//stationid
- c_sprvstg='WV'
- else if(hdrdat(9) >= four) then ! WV deep layer.mornitored set in convinfo file
- itype=247
- c_station_id='WV'//stationid
- c_sprvstg='WV'
+! Extra block for new JMA BUFR: Start
+ else if(istype == 5)then ! new JMA BUFR
+ if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
+ c_prvstg='JMA'
+ if(ihdr9 == 1) then ! IR winds
+! itype=252
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ else if(ihdr9 == 2) then ! visible winds
+! itype=242
+ c_station_id='VI'//stationid
+ c_sprvstg='VI'
+ else if(ihdr9 == 3) then ! WV cloud top
+! itype=250
+ c_station_id='WV'//stationid
+ c_sprvstg='WV'
+ else if(ihdr9 >= 4) then ! WV deep layer,monitoring
+! itype=250
+ qm=9 ! quality mark as 9, means the observation error needed to be set
+ c_station_id='WV'//stationid
+ c_sprvstg='WV'
+ endif
+! get quality information THIS SECTION NEEDS TO BE TESTED!!!
+ call ufbint(lunin,rep_array,1,1,iret, '{AMVIVR}')
+ irep_array = max(1,int(rep_array))
+ allocate( amvivr(2,irep_array))
+ call ufbrep(lunin,amvivr,2,irep_array,iret, 'TCOV CVWD')
+ pct1 = amvivr(2,1) ! use of pct1 (a new variable in the BUFR) is introduced by Nebuda/Genkova
+ deallocate( amvivr )
+ call ufbseq(lunin,amvqic,2,4,iret, 'AMVQIC') ! AMVQIC:: GNAPS PCCF
+ qifn = amvqic(2,2) ! QI w/ fcst does not exist in this BUFR
+ ee = amvqic(2,4) ! NOTE: GOES-R's ee is in [m/s]
+ if(qifn <85.0_r_kind ) then ! qifn, QI without forecast
+ qm=15
+ endif
+! Extra block for new JMA BUFR: End
+ else if(istype == 7)then ! NESDIS GOES
+ if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
+ c_prvstg='NESDIS'
+ if(ihdr9 == 1) then ! IR winds
+ if(hdrdat(12) <50000000000000.0_r_kind) then ! for channel 4
+! itype=245
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ else
+! itype=240 ! short wave winds
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
endif
- call ufbrep(lunin,qcdat,3,8,iret,qcstr)
+ else if(ihdr9 == 2) then ! visible winds
+! itype=251
+ c_station_id='VI'//stationid
+ c_sprvstg='VI'
+ else if(ihdr9 == 3) then ! WV cloud top
+! itype=246
+ c_station_id='WV'//stationid
+ c_sprvstg='WV'
+ else if(ihdr9 >= 4) then ! WV deep layer.mornitored set in convinfo file
+! itype=247
+ c_station_id='WV'//stationid
+ c_sprvstg='WV'
+ endif
! get quality information
- do j=1,8
- if( qify <=r105 .and. qifn r105 ) then
- qifn=qcdat(3,j)
- else if(qcdat(2,j) == three .and. qify >r105) then
- qify=qcdat(3,j)
- else if( qcdat(2,j) == four .and. ee >r105) then
- ee=qcdat(3,j)
- endif
+ do j=1,8
+ if( qify <=r105 .and. qifn r105 ) then
+ qifn=qcdat(3,j)
+ else if(qcdat(2,j) == three .and. qify >r105) then
+ qify=qcdat(3,j)
+ else if( qcdat(2,j) == four .and. ee >r105) then
+ ee=qcdat(3,j)
endif
- enddo
-!QI not applied to CAWV for now - may in the future
- if(qifn <85.0_r_kind .and. itype /= 247) then
- qm=15
endif
- if(wrf_nmm_regional) then
+ enddo
+!QI not applied to CAWV for now - may in the future
+ if(qifn <85.0_r_kind .and. itype /= 247) then
+ qm=15
+ endif
+ if(wrf_nmm_regional) then
! Minimum speed requirement for CAWV of 8m/s for HWRF.
! Tighten QC for 247 winds by removing winds below 450hPa
- if(itype == 247 .and. obsdat(4) < 8.0_r_kind .and. ppb > 450.0_r_kind) then
- qm=15
+ if(itype == 247 .and. obsdat(4) < 8.0_r_kind .and. ppb > 450.0_r_kind) then
+ qm=15
! Tighten QC for 240 winds by remove winds above 700hPa
- elseif(itype == 240 .and. ppb < 700.0_r_kind) then
- qm=15
+ elseif(itype == 240 .and. ppb < 700.0_r_kind) then
+ qm=15
! Tighten QC for 251 winds by remove winds above 750hPa
- elseif(itype == 251 .and. ppb < 750.0_r_kind) then
- qm=15
- endif
- else
+ elseif(itype == 251 .and. ppb < 750.0_r_kind) then
+ qm=15
+ endif
+ else
! Minimum speed requirement for CAWV of 10m/s
- if(itype == 247 .and. obsdat(4) < 10.0_r_kind) then
- qm=15
- endif
+ if(itype == 247 .and. obsdat(4) < 10.0_r_kind) then
+ qm=15
endif
endif
- else if(trim(subset) == 'NC005070' .or. trim(subset) == 'NC005071') then ! MODIS
- if(hdrdat(1) >=r700 .and. hdrdat(1) <= r799 ) then
- c_prvstg='MODIS'
- if(hdrdat(9) == one) then ! IR winds
- itype=257
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- else if(hdrdat(9) == three) then ! WV cloud top
- itype=258
- c_station_id='WV'//stationid
- c_sprvstg='WVCLOP'
- else if(hdrdat(9) >= four) then ! WV deep layer
- itype=259
- c_station_id='WV'//stationid
- c_sprvstg='WVDLAYER'
- endif
+ else if(istype == 8) then ! MODIS
+ c_prvstg='MODIS'
+ if(ihdr9 == 1) then ! IR winds
+! itype=257
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ else if(ihdr9 == 3) then ! WV cloud top
+! itype=258
+ c_station_id='WV'//stationid
+ c_sprvstg='WVCLOP'
+ else if(ihdr9 >= 4) then ! WV deep layer
+! itype=259
+ c_station_id='WV'//stationid
+ c_sprvstg='WVDLAYER'
+ endif
! get quality information
- call ufbrep(lunin,qcdat,3,8,iret,qcstr)
- do j=1,8
- if( qify <=r105 .and. qifn r105) then
- qifn=qcdat(3,j)
- else if(qcdat(2,j) == three .and. qify >r105) then
- qify=qcdat(3,j)
- else if( qcdat(2,j) == four .and. ee >r105 ) then
- ee=qcdat(3,j)
- endif
+ do j=1,8
+ if( qify <=r105 .and. qifn r105) then
+ qifn=qcdat(3,j)
+ else if(qcdat(2,j) == three .and. qify >r105) then
+ qify=qcdat(3,j)
+ else if( qcdat(2,j) == four .and. ee >r105 ) then
+ ee=qcdat(3,j)
endif
- enddo
- endif
- else if( trim(subset) == 'NC005080') then ! AVHRR
- if(hdrdat(1) <10.0_r_kind .or. (hdrdat(1) >= 200.0_r_kind .and. &
- hdrdat(1) <=223.0_r_kind) ) then
- c_prvstg='AVHRR'
- if(hdrdat(9) == one) then ! IR winds
- itype=244
- else
- write(6,*) 'READ_SATWND: wrong derived method value'
endif
+ enddo
+ else if(istype == 9) then ! AVHRR
+ c_prvstg='AVHRR'
+! itype=244
! get quality information
- call ufbrep(lunin,qcdat,3,8,iret,qcstr)
- do j=1,6
- if( qify <=r105 .and. qifn r105) then
- qifn=qcdat(3,j)
- else if(qcdat(2,j) == three .and. qify >r105) then
- qify=qcdat(3,j)
- else if( qcdat(2,j) == four .and. ee >r105) then
- ee=qcdat(3,j)
- endif
+ do j=1,6
+ if( qify <=r105 .and. qifn r105) then
+ qifn=qcdat(3,j)
+ else if(qcdat(2,j) == three .and. qify >r105) then
+ qify=qcdat(3,j)
+ else if( qcdat(2,j) == four .and. ee >r105) then
+ ee=qcdat(3,j)
endif
- enddo
- endif
- else if( trim(subset) == 'NC005019') then ! GOES shortwave winds
- if(hdrdat(1) >=r250 .and. hdrdat(1) <=r299 ) then ! The range of NESDIS satellite IDS
- c_prvstg='NESDIS'
- if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
- if(hdrdat(9) == one) then ! short wave IR winds
- itype=240
- c_station_id='IR'//stationid
- c_sprvstg='IR'
endif
+ enddo
+! Extra block for new Metop/AVHRR BUFR: Start
+ else if(istype == 10) then ! Metop-B/C from EUMETSAT
+ c_prvstg='METOP'
+ if(ihdr9 == 1) then ! IRwinds
+! itype=244
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ else
+ write(6,*) 'READ_SATWND: wrong derived method value'
+ endif
+ call ufbint(lunin,rep_array,1,1,iret, '{AMVIVR}')
+ irep_array = int(rep_array)
+ allocate( amvivr(2,irep_array))
+ call ufbrep(lunin,amvivr,2,irep_array,iret, 'TCOV CVWD')
+ pct1 = amvivr(2,1) ! use of pct1 is limited to GOES-16/17) as introduced by Nebuda/Genkova
+ deallocate( amvivr )
+ call ufbseq(lunin,amvqic,2,4,iret, 'AMVQIC') ! AMVQIC:: GNAPS PCCF
+ qifn = amvqic(2,2) ! QI w/ fcst does not exist in this BUFR
+ ee = amvqic(2,4) ! NOTE: GOES-R's ee is in [m/s]
+! Extra block for new Metop/AVHRR BUFR: End
+ else if(istype == 11) then ! GOES shortwave winds
+ if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
+ c_prvstg='NESDIS'
+ if(ihdr9 == 1) then ! short wave IR winds
+! itype=240
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ endif
! get quality information
- call ufbrep(lunin,qcdat,3,8,iret,qcstr)
- do j=1,6
- if( qify <=r105 .and. qifn r105) then
- qifn=qcdat(3,j)
- else if(qcdat(2,j) == three .and. qify >r105) then
- qify=qcdat(3,j)
- else if( qcdat(2,j) == four .and. ee >r105) then
- ee=qcdat(3,j)
- endif
+ do j=1,6
+ if( qify <=r105 .and. qifn r105) then
+ qifn=qcdat(3,j)
+ else if(qcdat(2,j) == three .and. qify >r105) then
+ qify=qcdat(3,j)
+ else if( qcdat(2,j) == four .and. ee >r105) then
+ ee=qcdat(3,j)
endif
- enddo
-! Tighten QC for 240 winds by removing winds above 700hPa
- if(wrf_nmm_regional) then
- if(itype == 240 .and. ppb < 700.0_r_kind) qm=15
endif
+ enddo
+! Tighten QC for 240 winds by removing winds above 700hPa
+ if(wrf_nmm_regional) then
+ if(itype == 240 .and. ppb < 700.0_r_kind) qm=15
endif
- else if( trim(subset) == 'NC005072') then ! LEOGEO (LeoGeo) winds
+ else if(istype == 12) then ! LEOGEO (LeoGeo) winds
if(hdrdat(1) ==854 ) then ! LEOGEO satellite ID
c_prvstg='LEOGEO'
- if(hdrdat(9) == one) then !LEOGEO IR winds
- itype=255
+ if(ihdr9 == 1) then !LEOGEO IR winds
+! itype=255
c_station_id='IR'//stationid
c_sprvstg='IR'
endif
! get quality information
- call ufbrep(lunin,qcdat,3,8,iret,qcstr)
!!! Rethink this strategy!!!
qifn=qcdat(3,1)
qify=qcdat(3,2)
@@ -945,303 +1141,206 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
!endif
!enddo
endif
- else if( trim(subset) == 'NC005090') then ! VIIRS IR winds
- if(hdrdat(1) >=r200 .and. hdrdat(1) <=r250 ) then ! The range of satellite IDS
- c_prvstg='VIIRS'
- if(hdrdat(9) == one) then ! VIIRS IR winds
- itype=260
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- endif
+ else if(istype == 13) then ! VIIRS IR winds
+ c_prvstg='VIIRS'
+ if(ihdr9 == 1) then ! VIIRS IR winds
+! itype=260
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ endif
! get quality information
- call ufbrep(lunin,qcdat,3,8,iret,qcstr)
- do j=1,6
- if( qify <=r105 .and. qifn r105) then
- qifn=qcdat(3,j)
- else if(qcdat(2,j) == three .and. qify >r105) then
- qify=qcdat(3,j)
- else if( qcdat(2,j) == four .and. ee >r105) then
- ee=qcdat(3,j)
- endif
+ do j=1,6
+ if( qify <=r105 .and. qifn r105) then
+ qifn=qcdat(3,j)
+ else if(qcdat(2,j) == three .and. qify >r105) then
+ qify=qcdat(3,j)
+ else if( qcdat(2,j) == four .and. ee >r105) then
+ ee=qcdat(3,j)
endif
- enddo
- endif
+ endif
+ enddo
if(qifn <85.0_r_kind ) then ! qifn, QI without forecast
qm=15
endif
-! Extra block for new JMA BUFR: Start
- else if(trim(subset) == 'NC005047' .or. trim(subset) == 'NC005048' .or. &
- trim(subset) == 'NC005049') then ! read new JMA BURF
- if( hdrdat(1) >=r100 .and. hdrdat(1) <=r199 ) then ! The range of satellite IDs
- c_prvstg='JMA'
- if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
- if(hdrdat(9) == one) then ! IR winds
- itype=252
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- else if(hdrdat(9) == two) then ! visible winds
- itype=242
- c_station_id='VI'//stationid
- c_sprvstg='VI'
- else if(hdrdat(9) == three) then ! WV cloud top
- itype=250
- c_station_id='WV'//stationid
- c_sprvstg='WV'
- else if(hdrdat(9) >= four) then ! WV deep layer,monitoring
- itype=250
- qm=9 ! quality mark as 9, means the observation error needed to be set
- c_station_id='WV'//stationid
- c_sprvstg='WV'
- endif
-! get quality information THIS SECTION NEEDS TO BE TESTED!!!
- call ufbint(lunin,rep_array,1,1,iret, '{AMVIVR}')
- irep_array = int(rep_array)
- allocate( amvivr(2,irep_array))
- call ufbrep(lunin,amvivr,2,irep_array,iret, 'TCOV CVWD')
- pct1 = amvivr(2,1) ! use of pct1 (a new variable in the BUFR) is introduced by Nebuda/Genkova
- deallocate( amvivr )
- call ufbseq(lunin,amvqic,2,4,iret, 'AMVQIC') ! AMVQIC:: GNAPS PCCF
- qifn = amvqic(2,2) ! QI w/ fcst does not exist in this BUFR
- ee = amvqic(2,4) ! NOTE: GOES-R's ee is in [m/s]
- if(qifn <85.0_r_kind ) then ! qifn, QI without forecast
- qm=15
- endif
- endif
-! Extra block for new JMA BUFR: End
-! Extra block for new EUMETSAT BUFR: Start
- else if(trim(subset) == 'NC005067' .or. trim(subset) == 'NC005068' .or. &
- trim(subset) == 'NC005069') then ! read new EUM BURF
- if( hdrdat(1) = r50 ) then ! The range of satellite IDs
- c_prvstg='EUMETSAT'
- if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
- if(hdrdat(9) == one) then ! IR winds
- itype=253
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- else if(hdrdat(9) == two) then ! visible winds
- itype=243
- c_station_id='VI'//stationid
- c_sprvstg='VI'
- else if(hdrdat(9) == three) then ! WV cloud top, try to assimilate
- itype=254
- c_station_id='WV'//stationid
- c_sprvstg='WV'
- else if(hdrdat(9) >= four) then ! WV deep layer,monitoring
- itype=254
- qm=9 ! quality mark as 9, means the observation error needed to be set
- c_station_id='WV'//stationid
- c_sprvstg='WV'
- endif
-! get quality information THIS SECTION NEEDS TO BE TESTED!!!
- call ufbint(lunin,rep_array,1,1,iret, '{AMVIVR}')
- irep_array = int(rep_array)
- allocate( amvivr(2,irep_array))
- call ufbrep(lunin,amvivr,2,irep_array,iret, 'TCOV CVWD')
- pct1 = amvivr(2,1) ! use of pct1 (a new variable in the BUFR) is introduced by Nebuda/Genkova
- deallocate( amvivr )
- call ufbseq(lunin,amvqic,2,4,iret, 'AMVQIC') ! AMVQIC:: GNAPS PCCF
- qifn = amvqic(2,2) ! QI w/ fcst does not exist in this BUFR
- ee = amvqic(2,4) ! NOTE: GOES-R's ee is in [m/s]
- if(qifn <85.0_r_kind ) then ! qifn, QI without forecast
- qm=15
- endif
- endif
-! Extra block for new EUMETSAT BUFR: End
-! Extra block for new Metop/AVHRR BUFR: Start
- else if(trim(subset) == 'NC005081') then ! Metop-B/C from NESDIS
- if( hdrdat(1) <10.0_r_kind ) then ! The range of satellite IDs
- c_prvstg='METOP'
- if(hdrdat(9) == one) then ! IRwinds
- itype=244
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- else
- write(6,*) 'READ_SATWND: wrong derived method value'
- endif
- call ufbint(lunin,rep_array,1,1,iret, '{AMVIVR}')
- irep_array = int(rep_array)
- allocate( amvivr(2,irep_array))
- call ufbrep(lunin,amvivr,2,irep_array,iret, 'TCOV CVWD')
- pct1 = amvivr(2,1) ! use of pct1 is limited to GOES-16/17) as introduced by Nebuda/Genkova
- deallocate( amvivr )
- call ufbseq(lunin,amvqic,2,4,iret, 'AMVQIC') ! AMVQIC:: GNAPS PCCF
- qifn = amvqic(2,2) ! QI w/ fcst does not exist in this BUFR
- ee = amvqic(2,4) ! NOTE: GOES-R's ee is in [m/s]
- endif
-! Extra block for new Metop/AVHRR BUFR: End
! Extra block for VIIRS NOAA-20: Start
- else if(trim(subset) == 'NC005091') then
- if( hdrdat(1) >=r200 .and. hdrdat(1) <=r250 ) then ! Use this range in v16.*
- c_prvstg='VIIRS'
- if(trim(subset) == 'NC005091') then ! IR LW winds
- itype=260
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- !write(6,*)'itype= ',itype
- endif
-
-! call ufbint(lunin,rep_array,1,1,iret, '{AMVAHA}')
-! irep_array = int(rep_array)
-! allocate( amvaha(4,irep_array))
-! call ufbint(lunin,amvaha,4,irep_array,iret, 'EHAM PRLC TMDBST
-! HOCT')
-! deallocate( amvaha )
+ else if(istype == 14) then
+ c_prvstg='VIIRS' ! IR LW winds
+! itype=260
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ !write(6,*)'itype= ',itype
+
+! call ufbint(lunin,rep_array,1,1,iret, '{AMVAHA}')
+! irep_array = int(rep_array)
+! allocate( amvaha(4,irep_array))
+! call ufbint(lunin,amvaha,4,irep_array,iret, 'EHAM PRLC TMDBST
+! HOCT')
+! deallocate( amvaha )
!
-! call ufbint(lunin,rep_array,1,1,iret, '{AMVIII}')
-! irep_array = int(rep_array)
-! allocate( amviii(12,irep_array))
-! call ufbrep(lunin,amviii,12,irep_array,iret, 'LTDS SCLF SAID
-! SIID CHNM SCCF ORBN SAZA BEARAZ EHAM PRLC TMDBST')
-! deallocate( amviii )
-
- call ufbint(lunin,rep_array,1,1,iret, '{AMVIVR}')
- irep_array = int(rep_array)
- allocate( amvivr(2,irep_array))
- call ufbrep(lunin,amvivr,2,irep_array,iret, 'TCOV CVWD')
- pct1 = amvivr(2,1) ! use of pct1 (a new variable in the BUFR) is introduced by Nebuda/Genkova
- deallocate( amvivr )
-
-! call ufbrep(lunin,rep_array,1,1,iret, '{AMVCLD}')
-! irep_array = int(rep_array)
-! allocate( amvcld(12,irep_array))
-! ! MUCE --> MUNCEX within the new GOES16/17 and NOAA-20 VIIRS
-! sequence (I.Genkova, J.Whiting)
-! ! THIS CHANGE HAS NOT BEEN TESTED !!!
-! !call ufbrep(lunin,amvcld,12,irep_array,iret, 'FOST CDTP MUCE
-! VSAT TMDBST VSAT CDTP MUCE OECS CDTP HOCT COPT')
-! call ufbrep(lunin,amvcld,12,irep_array,iret, 'FOST CDTP MUNCEX
-! VSAT TMDBST VSAT CDTP MUNCEX OECS CDTP HOCT COPT')
-! deallocate( amvcld )
-
- call ufbseq(lunin,amvqic,2,4,iret, 'AMVQIC') ! AMVQIC:: GNAPS PCCF
- qifn = amvqic(2,2) ! QI w/ fcst does not exist in this BUFR
- ee = amvqic(2,4) ! NOTE: GOES-R's ee is in [m/s]
- endif
+! call ufbint(lunin,rep_array,1,1,iret, '{AMVIII}')
+! irep_array = int(rep_array)
+! allocate( amviii(12,irep_array))
+! call ufbrep(lunin,amviii,12,irep_array,iret, 'LTDS SCLF SAID
+! SIID CHNM SCCF ORBN SAZA BEARAZ EHAM PRLC TMDBST')
+! deallocate( amviii )
+
+ call ufbint(lunin,rep_array,1,1,iret, '{AMVIVR}')
+ irep_array = int(rep_array)
+ allocate( amvivr(2,irep_array))
+ call ufbrep(lunin,amvivr,2,irep_array,iret, 'TCOV CVWD')
+ pct1 = amvivr(2,1) ! use of pct1 (a new variable in the BUFR) is introduced by Nebuda/Genkova
+ deallocate( amvivr )
+
+! call ufbrep(lunin,rep_array,1,1,iret, '{AMVCLD}')
+! irep_array = int(rep_array)
+! allocate( amvcld(12,irep_array))
+! ! MUCE --> MUNCEX within the new GOES16/17 and NOAA-20 VIIRS
+! sequence (I.Genkova, J.Whiting)
+! ! THIS CHANGE HAS NOT BEEN TESTED !!!
+! !call ufbrep(lunin,amvcld,12,irep_array,iret, 'FOST CDTP MUCE
+! VSAT TMDBST VSAT CDTP MUCE OECS CDTP HOCT COPT')
+! call ufbrep(lunin,amvcld,12,irep_array,iret, 'FOST CDTP MUNCEX
+! VSAT TMDBST VSAT CDTP MUNCEX OECS CDTP HOCT COPT')
+! deallocate( amvcld )
+
+ call ufbseq(lunin,amvqic,2,4,iret, 'AMVQIC') ! AMVQIC:: GNAPS PCCF
+ qifn = amvqic(2,2) ! QI w/ fcst does not exist in this BUFR
+ ee = amvqic(2,4) ! NOTE: GOES-R's ee is in [m/s]
! Extra block for VIIRS NOAA20: End
! Extra block for GOES-R winds: Start
- else if(trim(subset) == 'NC005030' .or. trim(subset) == 'NC005031' .or. trim(subset) == 'NC005032' .or. & !IR(LW) / CS WV / VIS GOES-R like winds
- trim(subset) == 'NC005034' .or. trim(subset) == 'NC005039' ) then !CT WV / IR(SW) GOES-R like winds
-
- if(hdrdat(1) >=r250 .and. hdrdat(1) <=r299 ) then ! the range of NESDIS satellite IDs
- ! The sample newBUFR has SAID=259 (GOES-15)
- ! When GOES-R SAID is assigned, pls check
- ! if this range is still valid (Genkova))
- c_prvstg='NESDIS'
+ else if (istype >= 15 .and. istype <=20)then
+
+ c_prvstg='GOESR'
+ if(istype == 15) then ! IR LW winds
if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
- if(trim(subset) == 'NC005030') then ! IR LW winds
- itype=245
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- !write(6,*)'itype= ',itype
- else if(trim(subset) == 'NC005039') then ! IR SW winds
- itype=240
- c_station_id='IR'//stationid
- c_sprvstg='IR'
- !write(6,*)'itype= ',itype
- else if(trim(subset) == 'NC005032') then ! VIS winds
- itype=251
- c_station_id='VI'//stationid
- c_sprvstg='VI'
- !write(6,*)'itype= ',itype
- else if(trim(subset) == 'NC005034') then ! WV cloud top
- itype=246
- c_station_id='WV'//stationid
- c_sprvstg='WV'
- !write(6,*)'itype= ',itype
- else if(trim(subset) == 'NC005031') then ! WV clear sky/deep layer
- itype=247
- c_station_id='WV'//stationid
- c_sprvstg='WV'
+! itype=245
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ !write(6,*)'itype= ',itype
+ else if(istype == 16) then ! IR SW winds
+ if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
+! itype=240
+ c_station_id='IR'//stationid
+ c_sprvstg='IRSW'
+ !write(6,*)'itype= ',itype
+ else if(istype == 17) then ! VIS winds
+ if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
+! itype=251
+ c_station_id='VI'//stationid
+ c_sprvstg='VIS'
!write(6,*)'itype= ',itype
- endif
+ else if(istype == 18) then ! WV cloud top
+ if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
+! itype=246
+ c_station_id='WV'//stationid
+ c_sprvstg='WVCT'
+ !write(6,*)'itype= ',itype
+ else if(istype == 19) then ! WV clear sky/deep layer
+ if(hdrdat(10) >68.0_r_kind) cycle loop_readsb ! reject data zenith angle >68.0 degree
+! itype=247
+ c_station_id='WV'//stationid
+ c_sprvstg='WVCS'
+ !write(6,*)'itype= ',itype
+ else if(istype == 20) then ! WV clear sky/deep layer
+ hdrdat(10)=61.23 ! set zenith angle for CIMSS AMVs to 67 to pass QC, no value in origional data
+! itype=241
+ c_station_id='IR'//stationid
+ c_sprvstg='IR'
+ endif
-! call ufbint(lunin,rep_array,1,1,iret, '{AMVAHA}')
-! irep_array = int(rep_array)
-! allocate( amvaha(4,irep_array))
-! call ufbint(lunin,amvaha,4,irep_array,iret, 'EHAM PRLC TMDBST HOCT')
-! deallocate( amvaha )
-!
-! call ufbint(lunin,rep_array,1,1,iret, '{AMVIII}')
-! irep_array = int(rep_array)
-! allocate( amviii(12,irep_array))
-! call ufbrep(lunin,amviii,12,irep_array,iret, 'LTDS SCLF SAID SIID CHNM SCCF ORBN SAZA BEARAZ EHAM PRLC TMDBST')
-! deallocate( amviii )
-
- call ufbint(lunin,rep_array,1,1,iret, '{AMVIVR}')
- irep_array = int(rep_array)
- allocate( amvivr(2,irep_array))
- call ufbrep(lunin,amvivr,2,irep_array,iret, 'TCOV CVWD')
- pct1 = amvivr(2,1) ! use of pct1 (a new variable in the BUFR) is introduced by Nebuda/Genkova
- deallocate( amvivr )
-
-! call ufbrep(lunin,rep_array,1,1,iret, '{AMVCLD}')
-! irep_array = int(rep_array)
-! allocate( amvcld(12,irep_array))
-! call ufbrep(lunin,amvcld,12,irep_array,iret, 'FOST CDTP MUCE VSAT TMDBST VSAT CDTP MUCE OECS CDTP HOCT COPT')
-! deallocate( amvcld )
-
- call ufbseq(lunin,amvqic,2,4,iret, 'AMVQIC')
- qifn = amvqic(2,2) ! QI w/ fcst does not exist in this BUFR
- ee = amvqic(2,4) ! NOTE: GOES-R's ee is in [m/s]
+! call ufbint(lunin,rep_array,1,1,iret, '{AMVAHA}')
+! irep_array = int(rep_array)
+! allocate( amvaha(4,irep_array))
+! call ufbint(lunin,amvaha,4,irep_array,iret, 'EHAM PRLC TMDBST HOCT')
+! deallocate( amvaha )
+
+! call ufbint(lunin,rep_array,1,1,iret, '{AMVIII}')
+! irep_array = int(rep_array)
+! allocate( amviii(12,irep_array))
+! call ufbrep(lunin,amviii,12,irep_array,iret, 'LTDS SCLF SAID SIID CHNM SCCF ORBN SAZA BEARAZ EHAM PRLC TMDBST')
+! deallocate( amviii )
+
+ if (itype /= 241) then
+
+ call ufbint(lunin,rep_array,1,1,iret, '{AMVIVR}')
+ irep_array = int(rep_array)
+ allocate( amvivr(2,irep_array))
+ call ufbrep(lunin,amvivr,2,irep_array,iret, 'TCOV CVWD')
+ pct1 = amvivr(2,1) ! use of pct1 (a new variable in the BUFR) is introduced by Nebuda/Genkova
+ deallocate( amvivr )
+
+! call ufbrep(lunin,rep_array,1,1,iret, '{AMVCLD}')
+! irep_array = int(rep_array)
+! allocate( amvcld(12,irep_array))
+! call ufbrep(lunin,amvcld,12,irep_array,iret, 'FOST CDTP MUCE VSAT TMDBST VSAT CDTP MUCE OECS CDTP HOCT COPT')
+! deallocate( amvcld )
+
+ call ufbseq(lunin,amvqic,2,4,iret, 'AMVQIC')
+ qifn = amvqic(2,2) ! QI w/ fcst does not exist in this BUFR
+ ee = amvqic(2,4) ! NOTE: GOES-R's ee is in [m/s]
! Additional QC introduced by Sharon Nebuda (for GOES-R winds from MSG proxy images)
- if (qifn < 80_r_kind .or. qifn > r100 ) qm=15 !reject data with low QI
- if (ppb < 125.0_r_kind) qm=15 !reject data above 125hPa: Trop check in setup.f90
- experr_norm = 10.0_r_kind - 0.1_r_kind * ee ! introduced by Santek/Nebuda
- if (obsdat(4) > 0.1_r_kind) then ! obsdat(4) is the AMV speed
- experr_norm = experr_norm/obsdat(4)
- else
- experr_norm = 100.0_r_kind
- end if
- if (experr_norm > 0.9_r_kind) qm=15 ! reject data with EE/SPD>0.9
-
- if(wrf_nmm_regional) then
- ! type 251 has been determine not suitable to be subjected to pct1 range check
- if(itype==240 .or. itype==245 .or. itype==246) then
- if (pct1 < 0.04_r_kind) qm=15
- if (pct1 > 0.50_r_kind) qm=15
- elseif (itype==251) then
- if (pct1 > 0.50_r_kind) qm=15
- endif
- else
- if(itype==240 .or. itype==245 .or. itype==246 .or. itype==251) then
- ! types 245 and 246 have been used to determine the acceptable pct1 range, but that pct1 range is applied to all GOES-R winds
- if (pct1 < 0.04_r_kind) qm=15
- if (pct1 > 0.50_r_kind) qm=15
- endif
- endif
+ if (qifn < 80_r_kind .or. qifn > r100 )then
+ qm=15 !reject data with low QI
+ else if (ppb < 125.0_r_kind) then
+ qm=15 !reject data above 125hPa: Trop check in setup.f90
+ else if (obsdat(4) > 0.1_r_kind) then ! obsdat(4) is the AMV speed
+ experr_norm = (10.0_r_kind - 0.1_r_kind * ee)/obsdat(4) ! introduced by Santek/Nebuda
+ if (experr_norm > 0.9_r_kind) qm=15 ! reject data with EE/SPD>0.9
+ else
+ qm=15
+ end if
+
+ if(wrf_nmm_regional) then
+ ! type 251 has been determine not suitable to be subjected to pct1 range check
+ if(itype==240 .or. itype==245 .or. itype==246 .or. itype==241) then
+ if (pct1 < 0.04_r_kind .or. pct1 > 0.50_r_kind) qm=15
+ elseif (itype==251) then
+ if (pct1 > 0.50_r_kind) qm=15
+ endif
+ else
+ if(itype==240 .or. itype==245 .or. itype==246 .or. itype==251) then
+ ! types 245 and 246 have been used to determine the acceptable pct1 range, but that pct1 range is applied to all GOES-R winds
+ if (pct1 < 0.04_r_kind .or. pct1 > 0.50_r_kind) qm=15
+ endif
+ endif
! GOES-16 additional QC addopting ECMWF's approach(Katie Lean,14IWW)-start
- if (EC_AMV_QC) then
- if (qifn < 90_r_kind .or. qifn > r100 ) qm=15 ! stricter QI
- if (ppb < 150.0_r_kind) qm=15 ! all high level
- if (itype==251 .and. ppb < 700.0_r_kind) qm=15 ! VIS
- if (itype==246 .and. ppb > 300.0_r_kind) qm=15 ! WVCA
- dlon_earth=hdrdat(3)*deg2rad
- dlat_earth=hdrdat(2)*deg2rad
- call deter_sfc_type(dlat_earth,dlon_earth,t4dv,isflg,tsavg)
- if (isflg == 1 .and. ppb > 850.0_r_kind) qm=15 ! low over land
- endif
+ if (EC_AMV_QC) then
+ if (qifn < 90_r_kind .or. qifn > r100 ) qm=15 ! stricter QI
+ if (ppb < 150.0_r_kind) qm=15 ! all high level
+ if (itype==251 .and. ppb < 700.0_r_kind) qm=15 ! VIS
+ if (itype==246 .and. ppb > 300.0_r_kind) qm=15 ! WVCA
+ if (qm < 15)then
+ dlon_earth=hdrdat(3)*deg2rad
+ dlat_earth=hdrdat(2)*deg2rad
+ call deter_sfc_type(dlat_earth,dlon_earth,t4dv,isflg,tsavg)
+ if (isflg == 1 .and. ppb > 850.0_r_kind) qm=15 ! low over land
+ end if
+ endif
+
+ else ! Assign values for the mnemonics/variables missing in original datafile for type 241
+
+ call ufbint(lunin,hdrdat_005099,2,1,iret, 'GNAPS PCCF');
+ qifn=hdrdat_005099(2);
+ qm=2 ! do not reject the wind
+ pct1=0.4_r_kind ! do not reject the wind
+ ee=1.0_r_kind ! do not reject the wind
+
+ endif
! winds rejected by qc dont get used
- if (qm == 15) usage=r100
- if (qm == 3 .or. qm ==7) woe=woe*r1_2
+ if (qm == 3 .or. qm ==7) woe=woe*r1_2
! set strings for diagnostic output
- if(itype==240 ) then; c_prvstg='GOESR' ; c_sprvstg='IRSW' ; endif
- if(itype==245 ) then; c_prvstg='GOESR' ; c_sprvstg='IR' ; endif
- if(itype==246 ) then; c_prvstg='GOESR' ; c_sprvstg='WVCT' ; endif
- if(itype==247 ) then; c_prvstg='GOESR' ; c_sprvstg='WVCS' ; endif
- if(itype==251 ) then; c_prvstg='GOESR' ; c_sprvstg='VIS' ; endif
- endif
+
! Extra block for GOES-R winds: End
else ! wind is not recognised and itype is not assigned
+ write(6,*) 'read_satwnd: WIND IS NOT RECOGNIZED ',istype,itype
cycle loop_readsb
endif
- if ( itype == -1 ) cycle loop_readsb ! unassigned itype
-
! assign types and get quality info : end
if ( qify == zero) qify=r110
@@ -1274,8 +1373,6 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
call grdcrd1(dlon,rlons,nlon,1)
endif
-
-
!! detect surface type for IR winds monitoring over land for lat greter than 20N
! isflg - surface flag
! 0 sea
@@ -1284,7 +1381,7 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
! 3 snow
! 4 mixed
if( .not. twodvar_regional) then
- if(itype ==245 .or. itype ==252 .or. itype ==253 .or. itype ==240) then
+ if(itype ==245 .or. itype ==252 .or. itype ==253 .or. itype ==240 .or. itype ==241) then
if(hdrdat(2) >20.0_r_kind) then
call deter_sfc_type(dlat_earth,dlon_earth,t4dv,isflg,tsavg)
if(isflg /= 0) cycle loop_readsb
@@ -1386,7 +1483,7 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
endif ! end of njqc
if((itype==245 .or. itype==246) &
- .and. (trim(subset) == 'NC005010' .or. trim(subset) == 'NC005011' .or. trim(subset) == 'NC005012' )) then !only applies to AMVs from legacy algorithm (pre GOES-R)
+ .and. istype == 7) then !only applies to AMVs from legacy algorithm (pre GOES-R)
! using Santek quality control method,calculate the original ee value:
! NOTE: Up until GOES-R winds algorithm, EE (expected error, ee) is reported as percent 0-100% (the higher the ee, the better the wind quality)
! NOTE: In the new GOES-R BUFR, EE (expected error, ee) is reported in m/s (the smaller the ee, the better the wind quality)
@@ -1410,16 +1507,10 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
! Reduce OE for the GOES-R winds by half following Sharon Nebuda's work
! GOES-R wind are identified/recognised here by subset, but it could be done by itype or SAID
! After completing the evaluation of GOES-R winds, REVISE this section!!!
- if(trim(subset) == 'NC005030' .or. trim(subset) == 'NC005031' .or. trim(subset) == 'NC005032' .or. &
- trim(subset) == 'NC005034' .or. trim(subset) == 'NC005039' ) then
+ if(istype >= 15 .and. istype <=20)then
obserr=obserr/two
endif
-! Set usage variable
- usage = 0
- iuse=icuse(nc)
- if(iuse <= 0)usage=r100
- if(qm == 15 .or. qm == 12 .or. qm == 9)usage=r100
! if(itype==240) then; c_prvstg='NESDIS' ; c_sprvstg='IR' ; endif
! if(itype==242) then; c_prvstg='JMA' ; c_sprvstg='VI' ; endif
! if(itype==243) then; c_prvstg='EUMETSAT' ; c_sprvstg='VI' ; endif
@@ -1444,9 +1535,9 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
!! process the thining procedure
ithin=ithin_conv(nc)
- ithinp = ithin > 0 .and. ithin <5 .and. pflag /= 0
+ ithinp = ithin > 0 .and. ithin <5 .and. qm < 4
! if(ithinp .and. iuse >=0 )then
- if(ithinp )then
+ if(ithinp .and. pflag /= 0 )then
! Interpolate guess pressure profile to observation location
klon1= int(dlon); klat1= int(dlat)
dx = dlon-klon1; dy = dlat-klat1
@@ -1465,31 +1556,23 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
! Compute depth of guess pressure layersat observation location
end if
+
dlnpob=log(one_tenth*ppb) ! ln(pressure in cb)
ppb=one_tenth*ppb ! from mb to cb
! Special block for data thinning - if requested
- if (ithin > 0 .and. ithin <5 .and. iuse >=0 .and. qm <4) then
- ntmp=ndata ! counting moved to map3gridS
+ if (ithinp) then
! Set data quality index for thinning
if (thin4d) then
timedif = zero
else
timedif=abs(t4dv-toff)
endif
+ crit1 = timedif/r6+half
if(itype == 243 .or. itype == 253 .or. itype == 254) then
- if(qifn zero ) then
itime=int((tdiff+three)/ptime)+1
if (itime >ntime) itime=ntime
- if(pmot 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+2
- endif
- rusage(iout)=usage
- isort(ntb)=iout
- else
-! call map3grids_m_tm(-1,pflag,presl_thin,nlevp,ntime,dlat_earth,dlon_earth,&
- call map3grids_m_tm(-1,pflag,presl_thin,nlevp,dlat_earth,dlon_earth,&
- ppb,itime,crit1,ndata,iout,ntb,iiout,luse,maxobs,usage,rusage,.false.,.false.)
- if (ndata > ntmp) then
- nodata=nodata+2
- endif
- isort(ntb)=iout
- endif
- else
- if(pmot 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+2
- endif
- isort(ntb)=iout
- rusage(iout)=usage
- else
- call map3grids_m(-1,pflag,presl_thin,nlevp,dlat_earth,dlon_earth,&
- ppb,crit1,ndata,iout,ntb,iiout,luse,maxobs,usage,rusage,.false.,.false.)
- if (ndata > ntmp) then
- nodata=nodata+2
- endif
- isort(ntb)=iout
- endif
+ call map3grids_m_tm(-1,save_all,pflag,presl_thin,nlevp,dlat_earth,dlon_earth,&
+ ppb,itime,crit1,ndata,luse,maxobs,rthin,.false.,.false.)
+ else
+ call map3grids_m(-1,save_all,pflag,presl_thin,nlevp,dlat_earth,dlon_earth,&
+ ppb,crit1,ndata,luse,maxobs,rthin,.false.,.false.)
endif
+ if(.not. luse) cycle loop_readsb
else
ndata=ndata+1
- nodata=nodata+2
- iout=ndata
- isort(ntb)=iout
- rusage(iout)=usage
endif
+ iout=ndata
+ iuse=icuse(nc)
+ if(iuse < 0)qm = 9
+ if(qm > 7 .or. iuse < 0 )rusage(iout)=.false.
inflate_error=.false.
if (qm==3 .or. qm==7) inflate_error=.true.
woe=obserr
@@ -1574,7 +1624,7 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
cdata_all(11,iout)=qifn +1000.0_r_kind*qify ! quality indicator
cdata_all(12,iout)=qm ! quality mark
cdata_all(13,iout)=obserr ! original obs error
- cdata_all(14,iout)=usage ! usage parameter
+ cdata_all(14,iout)=0 ! usage parameter
cdata_all(15,iout)=idomsfc ! dominate surface type
cdata_all(16,iout)=tsavg ! skin temperature
cdata_all(17,iout)=ff10 ! 10 meter wind factor
@@ -1587,12 +1637,21 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
cdata_all(25,iout)=var_jb ! non linear qc parameter
cdata_all(26,iout)=one ! hilbert curve weight
cdata_all(27,iout)=obsdat(5) ! AMVQ for GOES-17 mitig.AMVs
+ ! extra variables for satwind qc for brett
+ cdata_all(28,iout)=hdrdat(9) ! wind computation method
+ cdata_all(29,iout)=hdrdat(10) ! satellite zenith angle
+ cdata_all(30,iout)=hdrdat(1) ! satellite identifier
+ cdata_all(31,iout)=qifn ! QI without forecast
+ cdata_all(32,iout)=qify ! QI with forecast
+ cdata_all(33,iout)=ee ! expected error
+ cdata_all(34,iout)=pct1
if(perturb_obs)then
- cdata_all(28,iout)=ran01dom()*perturb_fact ! u perturbation
- cdata_all(29,iout)=ran01dom()*perturb_fact ! v perturbation
+ cdata_all(35,iout)=ran01dom()*perturb_fact ! u perturbation
+ cdata_all(36,iout)=ran01dom()*perturb_fact ! v perturbation
endif
+
enddo loop_readsb
! End of bufr read loop
enddo loop_msg
@@ -1605,52 +1664,72 @@ subroutine read_satwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
deallocate(presl_thin)
call del3grids_tm
endif
-
! Normal exit
-
enddo loop_convinfo! loops over convinfo entry matches
deallocate(lmsg,tab,nrep)
! Close unit to bufr file
call closbf(lunin)
-
-
- ! Write header record and data to output file for further processing
- allocate(iloc(ndata))
- icount=0
- do i=1,maxobs
- if(isort(i) > 0)then
- icount=icount+1
- iloc(icount)=isort(i)
- end if
- end do
- if(ndata /= icount)then
- write(6,*) ' READ_SATWND: mix up in read_satwnd ,ndata,icount ',ndata,icount
- call stop2(49)
- end if
-
- allocate(cdata_out(nreal,ndata))
- do i=1,ndata
- itx=iloc(i)
- do k=1,13
- cdata_out(k,i)=cdata_all(k,itx)
+!
+ if(ndata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,ndata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' smar ',trim(ioctype(nc)),ictype(nc),icsubtype(nc),numall,numrem,numqc,numthin
+! If thinned data set usage
+ do i=1,ndata
+ if(rthin(i))then
+ cdata_all(12,i)=14
+ cdata_all(14,i)=101.0_r_kind
+ end if
+ if(.not. rusage(i))cdata_all(14,i) = 100.0_r_kind
end do
- cdata_out(14,i)=rusage(itx)
- do k=15,nreal
- cdata_out(k,i)=cdata_all(k,itx)
+ nxdata=ndata
+! If flag to not save thinned data is set - compress data
+ ndata=0
+ do i=1,nxdata
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 1) .or. &
+ (pmot == 2 .and. rusage(i) .and. .not. rthin(i)) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ ndata=ndata+1
+ do k=1,nreal
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
end do
- end do
- deallocate(iloc,isort,cdata_all,rusage)
+ nodata=nodata+2*ndata
+ end if
+ deallocate(rusage,rthin)
+
+
+ ! Write header record and data to output file for further processing
- call count_obs(ndata,nreal,ilat,ilon,cdata_out,nobs)
+ call count_obs(ndata,nreal,ilat,ilon,cdata_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon
- write(lunout) cdata_out
+ write(lunout) ((cdata_all(k,i),k=1,nreal),i=1,ndata)
+
+ deallocate(cdata_all)
- deallocate(cdata_out)
-900 continue
- if(diagnostic_reg .and. ntest>0) write(6,*)'READ_SATWND: ',&
+ if(diagnostic_reg)then
+ if(ntest>0) write(6,*)'READ_SATWND: ',&
'ntest,disterrmax=',ntest,disterrmax
- if(diagnostic_reg .and. nvtest>0) write(6,*)'READ_SATWND: ',&
+ if(nvtest>0) write(6,*)'READ_SATWND: ',&
'nvtest,vdisterrmax=',ntest,vdisterrmax
+ end if
if (ndata == 0) then
write(6,*)'READ_SATWND: closbf(',lunin,')'
diff --git a/src/gsi/read_sfcwnd.f90 b/src/gsi/read_sfcwnd.f90
index 05c96b21fc..07fed808c7 100644
--- a/src/gsi/read_sfcwnd.f90
+++ b/src/gsi/read_sfcwnd.f90
@@ -48,19 +48,19 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
use gridmod, only: diagnostic_reg,regional,nlon,nlat,nsig,&
tll2xy,txy2ll,rotate_wind_ll2xy,rotate_wind_xy2ll,&
rlats,rlons,fv3_regional
- use qcmod, only: errormod,noiqc,njqc
+ use qcmod, only: errormod,njqc
- use convthin, only: make3grids,map3grids,del3grids,use_all
+ use convthin, only: make3grids,map3grids_m,del3grids,use_all
use constants, only: deg2rad,zero,rad2deg,one_tenth,&
tiny_r_kind,huge_r_kind,r60inv,one_tenth,&
one,two,three,four,five,half,quarter,r60inv,r10,r100,r2000
use converr,only: etabl
use converr_uv,only: etabl_uv,isuble_uv,maxsub_uv
use convb_uv,only: btabl_uv
- use obsmod, only: ran01dom,bmiss
+ use obsmod, only: ran01dom,bmiss,reduce_diag
use convinfo, only: nconvtype, &
icuse,ictype,icsubtype,ioctype, &
- ithin_conv,rmesh_conv,pmesh_conv
+ ithin_conv,rmesh_conv,pmesh_conv,pmot_conv
use gsi_4dvar, only: l4dvar,l4densvar,iwinbgn,winlen,time_4dvar,thin4d
use deter_sfc_mod, only: deter_sfc_type,deter_sfc2
use mpimod, only: npe
@@ -97,13 +97,12 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
integer(i_kind) ireadmg,ireadsb,iuse,mxtb,nmsgmax
integer(i_kind) i,maxobs,idomsfc,nsattype,j,ncount
- integer(i_kind) nc,nx,isflg,itx,nchanl
+ integer(i_kind) nc,nx,isflg,nchanl
integer(i_kind) ntb,ntmatch,ncx,ncsave,ntread
integer(i_kind) kk,klon1,klat1,klonp1,klatp1
integer(i_kind) nmind,lunin,idate,ilat,ilon,iret,k
- integer(i_kind) nreal,ithin,iout,ntmp,icount,iiout,ii
+ integer(i_kind) nreal,ithin,iout,ii
integer(i_kind) itype,iosub,ixsub,isubsub,iobsub
- integer(i_kind) lim_qm
integer(i_kind) nlevp ! vertical level for thinning
integer(i_kind) pflag
integer(i_kind) ntest,nvtest
@@ -117,7 +116,7 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
integer(i_kind),dimension(nconvtype+1) :: ntx
integer(i_kind),dimension(5):: idate5
- integer(i_kind),allocatable,dimension(:):: isort,iloc,nrep
+ integer(i_kind),allocatable,dimension(:):: nrep
integer(i_kind),allocatable,dimension(:,:)::tab
! integer(i_kind) itypex,lcount,iflag,m
@@ -143,7 +142,13 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
real(r_double),dimension(5,4):: wnddat
real(r_double),dimension(1,1):: r_prvstg,r_sprvstg
real(r_kind),allocatable,dimension(:):: presl_thin
- real(r_kind),allocatable,dimension(:,:):: cdata_all,cdata_out
+ real(r_kind),allocatable,dimension(:,:):: cdata_all
+
+ logical,allocatable,dimension(:)::rthin,rusage
+ logical save_all
+! integer(i_kind) numthin,numqc,numrem,numall
+ integer(i_kind) nxdata,pmot
+
! equivalence to handle character names
equivalence(r_prvstg(1,1),c_prvstg)
@@ -200,11 +205,6 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
werrmin=one
nsattype=0
nreal=24
- if (noiqc) then
- lim_qm=8
- else
- lim_qm=4
- endif
! ** read convtype from convinfo file
! ** only read in OSCAT 291 for now **
@@ -239,7 +239,7 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
call getcount_bufr(infile,nmsgmax,mxtb)
- allocate(lmsg(nmsgmax,ntread),tab(mxtb,3),nrep(nmsgmax))
+ allocate(lmsg(nmsgmax,ntread),tab(mxtb,2),nrep(nmsgmax))
lmsg = .false.
maxobs=0
@@ -321,7 +321,6 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
end if
tab(ntb,1)=ncsave
tab(ntb,2)=nx
- tab(ntb,3)=1
lmsg(nmsg,nx) = .true.
end if
enddo loop_report
@@ -329,9 +328,7 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
! Loop over convinfo file entries; operate on matches
- allocate(cdata_all(nreal,maxobs),isort(maxobs))
- isort = 0
- cdata_all=zero
+ allocate(cdata_all(nreal,maxobs),rusage(maxobs),rthin(maxobs))
nread=0
ntest=0
nvtest=0
@@ -342,15 +339,19 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
!! read satellite winds one type a time
! same as in the read_prepbufr.f90 file
+ rusage = .true.
+ rthin = .false.
loop_convinfo: do nx=1,ntread
use_all = .true.
ithin=0
+ pmot=0
if(nx >1) then
nc=ntx(nx)
ithin=ithin_conv(nc)
if (ithin > 0 ) then
rmesh=rmesh_conv(nc)
pmesh=pmesh_conv(nc)
+ pmot = pmot_conv(nc)
use_all = .false.
if(pmesh > zero) then
pflag=1
@@ -376,6 +377,9 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
ioctype(nc),ictype(nc),rmesh,pflag,nlevp,pmesh,nc
endif
endif
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
call closbf(lunin)
close(lunin)
@@ -473,9 +477,7 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
if(obsdat(3) >=1) cycle loop_readsb
if(trim(subset) == 'NC012255') then ! OSCAT KNMI wind
- if( hdrdat(1) == r421) then
- itype=291
- endif
+ if( hdrdat(1) == r421) itype=291
endif
@@ -642,7 +644,6 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
! Special block for data thinning - if requested
if (ithin > 0 .and. iuse >=0) then
- ntmp=ndata ! counting moved to map3gridS
! Set data quality index for thinning
if (thin4d) then
@@ -659,22 +660,16 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
end do
endif
- call map3grids(-1,pflag,presl_thin,nlevp,dlat_earth,dlon_earth,&
- ppb,crit1,ndata,iout,ntb,iiout,luse,.false.,.false.)
+ call map3grids_m(-1,save_all,pflag,presl_thin,nlevp, &
+ dlat_earth,dlon_earth,ppb,crit1,ndata,&
+ luse,maxobs,rthin,.false.,.false.)
if (.not. luse) cycle loop_readsb
- if(iiout > 0) isort(iiout)=0
- if (ndata > ntmp) then
- nodata=nodata+2
- endif
- isort(ntb)=iout
else
ndata=ndata+1
- nodata=nodata+2
- iout=ndata
- isort(ntb)=iout
endif
+ iout=ndata
woe=obserr
oelev=r10
@@ -718,6 +713,7 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
cdata_all(22,iout)=r_prvstg(1,1) ! provider name
cdata_all(23,iout)=r_sprvstg(1,1) ! subprovider name
cdata_all(24,iout)=var_jb ! non linear qc parameter
+ if(usage >= r100)rusage(ndata)=.false.
enddo loop_readsb
@@ -729,43 +725,69 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
deallocate(presl_thin)
call del3grids
endif
+
! Normal exit
enddo loop_convinfo! loops over convinfo entry matches
call closbf(lunin)
deallocate(lmsg,nrep,tab)
-
- ! Write header record and data to output file for further processing
- allocate(iloc(ndata))
- icount=0
- do i=1,maxobs
- if(isort(i) > 0)then
- icount=icount+1
- iloc(icount)=isort(i)
- end if
- end do
- if(ndata /= icount)then
- write(6,*) ' READ_SFCWND: mix up in read_satwnd ,ndata,icount ',ndata,icount
- call stop2(49)
+ nxdata=ndata
+ ndata=0
+ if(nxdata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,nxdata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' sfc ',trim(ioctype(nc)),ictype(nc),icsubtype(nc),numall,numrem,numqc,numthin
+! If thinned data set usage
+ do i=1,nxdata
+ if(rthin(i))then
+ cdata_all(14,i)=101._r_kind
+ cdata_all(12,i)=14
+ end if
+ end do
+! If flag to not save thinned data is set - compress data
+ do i=1,nxdata
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 1) .or. &
+ (pmot == 2 .and. (rusage(i) .and. .not. rthin(i))) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ ndata=ndata+1
+ if(i > ndata)then
+ do k=1,nreal
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
+ end if
+ end do
+ nodata=nodata+ndata
end if
+ ! Write header record and data to output file for further processing
+ deallocate(rusage,rthin)
- allocate(cdata_out(nreal,ndata))
- do i=1,ndata
- itx=iloc(i)
- do k=1,nreal
- cdata_out(k,i)=cdata_all(k,itx)
- end do
- end do
- deallocate(iloc,isort,cdata_all)
! deallocate(etabl)
+ close(lunin)
- call count_obs(ndata,nreal,ilat,ilon,cdata_out,nobs)
+ call count_obs(ndata,nreal,ilat,ilon,cdata_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon
- write(lunout) cdata_out
+ write(lunout) ((cdata_all(k,i),k=1,nreal),i=1,ndata)
- deallocate(cdata_out)
-900 continue
+ deallocate(cdata_all)
+
if(diagnostic_reg .and. ntest>0) write(6,*)'READ_SFCWND: ',&
'ntest,disterrmax=',ntest,disterrmax
if(diagnostic_reg .and. nvtest>0) write(6,*)'READ_SFCWND: ',&
@@ -777,7 +799,6 @@ subroutine read_sfcwnd(nread,ndata,nodata,infile,obstype,lunout,gstime,twind,sis
write(6,*) 'READ_SFCWND,nread,ndata,nreal,nodata=',nread,ndata,nreal,nodata
- close(lunin)
! End of routine
return
diff --git a/src/gsi/read_ssmi.f90 b/src/gsi/read_ssmi.f90
index 3e47ee79b5..cece78ac03 100755
--- a/src/gsi/read_ssmi.f90
+++ b/src/gsi/read_ssmi.f90
@@ -132,7 +132,8 @@ subroutine read_ssmi(mype,val_ssmi,ithin,rmesh,jsatid,gstime,&
real(r_kind),parameter:: tbmin=70.0_r_kind
real(r_kind),parameter:: tbmax=320.0_r_kind
character(80),parameter:: hdr1b='SAID YEAR MNTH DAYS HOUR MINU SECO ORBN' !use for ufbint()
- character(40),parameter:: str1='CLAT CLON SFTG POSN SAZA' !use for ufbint()
+ character(40),parameter:: str1='CLATH CLONH SFTG POSN SAZA' !use for ufbint() new
+ character(40),parameter:: strx='CLAT CLON SFTG POSN SAZA' !use for ufbint() old
character(40),parameter:: str2='TMBR' !use for ufbrep()
! Declare local variables
@@ -302,6 +303,7 @@ subroutine read_ssmi(mype,val_ssmi,ithin,rmesh,jsatid,gstime,&
! SSM/I data are stored in groups of nscan, hence the loop.
call ufbint(lnbufr,midat,nloc,nscan,iret,str1)
+ if(midat(1,1)>10e8) call ufbint(lnbufr,midat,nloc,nscan,iret,strx)
!--- Extract brightness temperature data. Apply gross check to data.
@@ -309,7 +311,6 @@ subroutine read_ssmi(mype,val_ssmi,ithin,rmesh,jsatid,gstime,&
call ufbrep(lnbufr,mirad,1,nchanl*nscan,iret,str2)
-
ij=0
scan_loop: do js=1,nscan
@@ -511,7 +512,6 @@ subroutine read_ssmi(mype,val_ssmi,ithin,rmesh,jsatid,gstime,&
end do read_loop
end do read_subset
call closbf(lnbufr)
- close(lnbufr)
! If multiple tasks read input bufr file, allow each tasks to write out
! information it retained and then let single task merge files together
diff --git a/src/gsi/read_viirs.f90 b/src/gsi/read_viirs.f90
index 66923c9896..ab80642f29 100644
--- a/src/gsi/read_viirs.f90
+++ b/src/gsi/read_viirs.f90
@@ -198,6 +198,7 @@ subroutine read_sst_viirs(mype,val_viirs,ithin,rmesh,jsatid,&
bufsat = 226
else
write(*,*) 'READ_SST_VIIRS: Unrecognized value for jsatid '//jsatid//':RETURNING'
+ deallocate(amesh,hsst_thd)
return
end if
@@ -516,7 +517,7 @@ subroutine read_sst_viirs(mype,val_viirs,ithin,rmesh,jsatid,&
endif
! Deallocate local arrays
- deallocate(data_all)
+ deallocate(data_all,amesh,hsst_thd)
if(diagnostic_reg.and.ntest>0 .and. mype_sub==mype_root) &
write(6,*)'READ_VIIRS-M: ',&
diff --git a/src/gsi/read_wcpbufr.f90 b/src/gsi/read_wcpbufr.f90
index 41dc36f3f6..65e70f4be8 100644
--- a/src/gsi/read_wcpbufr.f90
+++ b/src/gsi/read_wcpbufr.f90
@@ -47,11 +47,11 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
tll2xy,txy2ll, rlats,rlons
use convinfo, only: nconvtype,ctwind, &
ncmiter,ncgroup,ncnumgrp,icuse,ictype,icsubtype,ioctype, &
- ithin_conv,rmesh_conv,pmesh_conv
+ ithin_conv,rmesh_conv,pmesh_conv,pmot_conv
use converr,only: etabl
- use obsmod, only: iadate, offtime_data, oberrflg
+ use obsmod, only: iadate, offtime_data, oberrflg,reduce_diag
use gsi_4dvar, only: l4dvar,l4densvar,time_4dvar,winlen,thin4d
- use convthin, only: make3grids,map3grids,del3grids,use_all
+ use convthin, only: make3grids,map3grids_m,del3grids,use_all
use mpimod, only: npe
implicit none
@@ -85,15 +85,15 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
character(8) c_station_id
character(1) sidchr(8)
- integer(i_kind) ireadmg,ireadsb,icntpnt,icntpnt2,icount,iiout
+ integer(i_kind) ireadmg,ireadsb,icntpnt,icntpnt2
integer(i_kind) lunin,i,maxobs,nmsgmax,mxtb
integer(i_kind) kk,klon1,klat1,klonp1,klatp1
- integer(i_kind) nc,nx,ntread,itx,ii,ncsave
+ integer(i_kind) nc,nx,ntread,ii,ncsave
integer(i_kind) ihh,idd,idate,iret,im,iy,k,levs
integer(i_kind) kx,nreal,nchanl,ilat,ilon,ithin
integer(i_kind) qm, swcpq, lwcpq
integer(i_kind) nlevp ! vertical level for thinning
- integer(i_kind) ntmp,iout
+ integer(i_kind) iout
integer(i_kind) pflag,irec
integer(i_kind) ntest,nvtest,iosub,ixsub,isubsub,iobsub
integer(i_kind) kl,k1,k2
@@ -105,7 +105,7 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
integer(i_kind),dimension(255):: pqm
integer(i_kind),dimension(nconvtype)::ntxall
integer(i_kind),dimension(nconvtype+1)::ntx
- integer(i_kind),allocatable,dimension(:):: isort,iloc,nrep
+ integer(i_kind),allocatable,dimension(:):: nrep
integer(i_kind),allocatable,dimension(:,:):: tab
real(r_kind) time,timex,timeobs,toff,t4dv,zeps
real(r_kind) rmesh,ediff,usage
@@ -125,7 +125,12 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
real(r_kind),dimension(nsig-1):: dpres
real(r_kind),dimension(255)::plevs
real(r_kind),allocatable,dimension(:):: presl_thin
- real(r_kind),allocatable,dimension(:,:):: cdata_all,cdata_out
+ real(r_kind),allocatable,dimension(:,:):: cdata_all
+ logical,allocatable,dimension(:)::rthin,rusage
+ logical save_all
+! integer(i_kind) numthin,numqc,numrem
+ integer(i_kind) nxdata,pmot,numall
+
real(r_double) rstation_id,qcmark_huge
real(r_double),dimension(8):: hdr
@@ -294,25 +299,28 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! loop over convinfo file entries; operate on matches
- allocate(cdata_all(nreal,maxobs),isort(maxobs))
- isort = 0
- cdata_all=zero
+ allocate(cdata_all(nreal,maxobs),rusage(maxobs),rthin(maxobs))
nread=0
ntest=0
nvtest=0
nchanl=0
ilon=2
ilat=3
+ rusage = .true.
+ rthin = .false.
loop_convinfo: do nx=1, ntread
use_all = .true.
ithin=0
+ pmot=0
+
if(nx > 1) then
nc=ntx(nx)
ithin=ithin_conv(nc)
if (ithin > 0 ) then
rmesh=rmesh_conv(nc)
pmesh=pmesh_conv(nc)
+ pmot=nint(pmot_conv(nc))
use_all = .false.
if(pmesh > zero) then
pflag=1
@@ -338,6 +346,9 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
trim(ioctype(nc)),ictype(nc),rmesh,pflag,nlevp,pmesh
endif
endif
+ if(reduce_diag .and. pmot < 2)pmot=pmot+2
+ save_all=.false.
+ if(pmot /= 2 .and. pmot /= 0) save_all=.true.
call closbf(lunin)
@@ -380,32 +391,32 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
call ufbint(lunin,hdr,8,1,iret,hdstr)
kx=hdr(5)
- if(abs(hdr(3))>r90 .or. abs(hdr(2))>r360) cycle loop_readsb
- if(hdr(2)== r360)hdr(2)=hdr(2)-r360
- if(hdr(2) < zero)hdr(2)=hdr(2)+r360
- dlon_earth_deg=hdr(2)
- dlat_earth_deg=hdr(3)
- dlon_earth=hdr(2)*deg2rad
- dlat_earth=hdr(3)*deg2rad
-
- if(regional)then
- call tll2xy(dlon_earth,dlat_earth,dlon,dlat,outside) ! convert to rotated coordinate
- if(diagnostic_reg) then
- call txy2ll(dlon,dlat,rlon00,rlat00)
- ntest=ntest+1
- cdist=sin(dlat_earth)*sin(rlat00)+cos(dlat_earth)*cos(rlat00)* &
- (sin(dlon_earth)*sin(rlon00)+cos(dlon_earth)*cos(rlon00))
- cdist=max(-one,min(cdist,one))
- disterr=acos(cdist)*rad2deg
- disterrmax=max(disterrmax,disterr)
- end if
- if(outside) cycle loop_readsb ! check to see if outside regional domain
- else
- dlat = dlat_earth
- dlon = dlon_earth
- call grdcrd1(dlat,rlats,nlat,1)
- call grdcrd1(dlon,rlons,nlon,1)
- endif
+ if(abs(hdr(3))>r90 .or. abs(hdr(2))>r360) cycle loop_readsb
+ if(hdr(2)== r360)hdr(2)=hdr(2)-r360
+ if(hdr(2) < zero)hdr(2)=hdr(2)+r360
+ dlon_earth_deg=hdr(2)
+ dlat_earth_deg=hdr(3)
+ dlon_earth=hdr(2)*deg2rad
+ dlat_earth=hdr(3)*deg2rad
+
+ if(regional)then
+ call tll2xy(dlon_earth,dlat_earth,dlon,dlat,outside) ! convert to rotated coordinate
+ if(diagnostic_reg) then
+ call txy2ll(dlon,dlat,rlon00,rlat00)
+ ntest=ntest+1
+ cdist=sin(dlat_earth)*sin(rlat00)+cos(dlat_earth)*cos(rlat00)* &
+ (sin(dlon_earth)*sin(rlon00)+cos(dlon_earth)*cos(rlon00))
+ cdist=max(-one,min(cdist,one))
+ disterr=acos(cdist)*rad2deg
+ disterrmax=max(disterrmax,disterr)
+ end if
+ if(outside) cycle loop_readsb ! check to see if outside regional domain
+ else
+ dlat = dlat_earth
+ dlon = dlon_earth
+ call grdcrd1(dlat,rlats,nlat,1)
+ call grdcrd1(dlon,rlons,nlon,1)
+ endif
!------------------------------------------------------------------------
@@ -430,28 +441,28 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
! Add obs reference time, then subtract analysis time to get obs time relative to analysis
- time_correction=float(minobs-minan)*r60inv
+ time_correction=real(minobs-minan,r_kind)*r60inv
else
time_correction=zero
end if
- timeobs=real(real(hdr(4),r_single),r_double)
- t4dv=timeobs + toff
- zeps=1.0e-8_r_kind
- if (t4dv -zeps) t4dv=zero
- if (t4dv>winlen.and.t4dv -zeps) t4dv=zero
+ if (t4dv>winlen.and.t4dvwinlen) cycle loop_readsb ! outside time window
- else
- if((real(abs(time)) > real(ctwind(nc)) .or. real(abs(time)) > real(twindin)))cycle loop_readsb ! outside time window
- endif
+ if (l4dvar.or.l4densvar) then
+ if (t4dvwinlen) cycle loop_readsb ! outside time window
+ else
+ if((real(abs(time)) > real(ctwind(nc)) .or. real(abs(time)) > real(twindin)))cycle loop_readsb ! outside time window
+ endif
- timex=time
+ timex=time
! Extract data information on levels
call ufbint(lunin,obsdat,5,255,levs,obstr)
@@ -550,9 +561,11 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
if(qm > 15 .or. qm < 0) cycle loop_k_levs
+! Set usage variable
+ usage = zero
+
! Special block for data thinning - if requested
if (ithin > 0) then
- ntmp=ndata ! counting moved to map3gridS
! Set data quality index for thinning
if (thin4d) then
@@ -568,9 +581,12 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
end do
endif
- call map3grids(-1,pflag,presl_thin,nlevp,dlat_earth,dlon_earth,&
- plevs(k),crit1,ndata,iout,icntpnt,iiout,luse,.false.,.false.)
+ call map3grids_m(-1,save_all,pflag,presl_thin,nlevp, &
+ dlat_earth,dlon_earth,plevs(k),crit1,ndata,&
+ luse,maxobs,rthin,.false.,.false.)
+
+ if(rthin(ndata))usage=101._r_kind
if (.not. luse) then
if(k==levs) then
cycle loop_readsb
@@ -578,26 +594,17 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
cycle LOOP_K_LEVS
endif
endif
- if(iiout > 0) isort(iiout)=0
- if(ndata > ntmp)then
- nodata=nodata+1
- end if
- isort(icntpnt)=iout
else
ndata=ndata+1
- nodata=nodata+1
- iout=ndata
- isort(icntpnt)=iout
endif
+ iout=ndata
if(ndata > maxobs) then
write(6,*)'READ_WCPBUFR: ***WARNING*** ndata > maxobs for ',obstype
ndata = maxobs
end if
-! Set usage variable
- usage = zero
if(icuse(nc) <= 0)usage=100._r_kind
@@ -610,6 +617,7 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
if(ncnumgrp(nc)>0 )then ! default cross validation on
if(mod(ndata+1,ncnumgrp(nc))== ncgroup(nc)-1)usage=ncmiter(nc)
end if
+ if(icuse(nc) <= 0 .or. qm >= 8) rusage(iout) = .false.
! Extract pressure level and quality marks
dlnpob=log(plevs(k)) ! ln(pressure in cb)
@@ -670,7 +678,6 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
deallocate(presl_thin)
call del3grids
endif
-
! Normal exit
enddo loop_convinfo! loops over convinfo entry matches
@@ -679,35 +686,56 @@ subroutine read_wcpbufr(nread,ndata,nodata,infile,obstype,lunout,twindin,sis,&
close(lunin)
deallocate(lmsg,tab,nrep)
-! Write header record and data to output file for further processing
- allocate(iloc(ndata))
- icount=0
- do i=1,maxobs
- if(isort(i) > 0)then
- icount=icount+1
- iloc(icount)=isort(i)
- end if
- end do
- if(ndata /= icount)then
- write(6,*) ' WCPBUFR: mix up in read_wcpbufr ,ndata,icount ',ndata,icount
- call stop2(50)
- end if
- allocate(cdata_out(nreal,ndata))
- do i=1,ndata
- itx=iloc(i)
- do k=1,nreal
- cdata_out(k,i)=cdata_all(k,itx)
+ nxdata=ndata
+ nodata=0
+ if(nxdata > 0)then
+! numthin=0
+! numqc=0
+! numrem=0
+! do i=1,nxdata
+! if(.not. rusage(i))then
+! numqc=numqc+1
+! else if(rthin(i))then
+! numthin=numthin+1
+! else
+! numrem=numrem+1
+! end if
+! end do
+! write(6,*) ' wcp ',trim(ioctype(nc)),ictype(nc),icsubtype(nc),numall,numrem,numqc,numthin
+! If thinned data set usage
+ do i=1,nxdata
+ if(rthin(i))cdata_all(11,i)=100._r_kind
end do
- end do
- deallocate(iloc,isort,cdata_all)
+! If flag to not save thinned data is set - compress data
+ do i=1,nxdata
+! pmot=0 - all obs - thin obs
+! pmot=1 - all obs
+! pmot=2 - use obs
+! pmot=3 - use obs + thin obs
+ if((pmot == 0 .and. .not. rthin(i)) .or. &
+ (pmot == 1) .or. &
+ (pmot == 2 .and. (rusage(i) .and. .not. rthin(i))) .or. &
+ (pmot == 3 .and. rusage(i))) then
+
+ ndata=ndata+1
+ do k=1,nreal
+ cdata_all(k,ndata)=cdata_all(k,i)
+ end do
+ end if
+ end do
+ nodata=nodata+ndata
+ end if
+
+ deallocate(rusage,rthin)
+
+! Write header record and data to output file for further processing
- call count_obs(ndata,nreal,ilat,ilon,cdata_out,nobs)
+ call count_obs(ndata,nreal,ilat,ilon,cdata_all,nobs)
write(lunout) obstype,sis,nreal,nchanl,ilat,ilon,ndata
- write(lunout) cdata_out
+ write(lunout) ((cdata_all(k,i),k=1,nreal),i=1,ndata)
- deallocate(cdata_out)
+ deallocate(cdata_all)
-900 continue
if(diagnostic_reg .and. ntest>0) write(6,*)'READ_WCPBUFR: ',&
'ntest,disterrmax=',ntest,disterrmax
if(diagnostic_reg .and. nvtest>0) write(6,*)'READ_WCPBUFR: ',&
diff --git a/src/gsi/reorg_metar_cloud.f90 b/src/gsi/reorg_metar_cloud.f90
index 2d947f2ef3..478d1ab363 100644
--- a/src/gsi/reorg_metar_cloud.f90
+++ b/src/gsi/reorg_metar_cloud.f90
@@ -264,9 +264,9 @@ subroutine reorg_metar_cloud(cdata,nreal,ndata,cdata_all,maxobs,ngrid)
min_dist = 1.e10_r_kind
do ic= 1,nsta_cld
ista = sta_cld(ic)
- dist = (float(i1)-cdata(2,ista))*(float(i1)-cdata(2,ista)) &
- +(float(j1)-cdata(3,ista))*(float(j1)-cdata(3,ista))
- if (dist < min_dist .and. dist < float(isprd2)) then
+ dist = (real(i1,r_kind)-cdata(2,ista))*(real(i1,r_kind)-cdata(2,ista)) &
+ +(real(j1,r_kind)-cdata(3,ista))*(real(j1,r_kind)-cdata(3,ista))
+ if (dist < min_dist .and. dist < real(isprd2,r_kind)) then
min_dist = dist
ista_min = ista
end if
@@ -318,8 +318,8 @@ subroutine reorg_metar_cloud(cdata,nreal,ndata,cdata_all,maxobs,ngrid)
enddo
cdata_all(24,iout) = cdata_all(2,iout) ! save observaion station i
cdata_all(25,iout) = cdata_all(3,iout) ! save observaion station j
- cdata_all(2,iout) = float(i1) ! grid index i
- cdata_all(3,iout) = float(j1) ! grid index j
+ cdata_all(2,iout) = real(i1,r_kind) ! grid index i
+ cdata_all(3,iout) = real(j1,r_kind) ! grid index j
cdata_all(23,iout)= min_dist ! distance from station
endif
endif
diff --git a/src/gsi/rfdpar.f90 b/src/gsi/rfdpar.f90
index 79fa959bcb..b679ed6448 100644
--- a/src/gsi/rfdpar.f90
+++ b/src/gsi/rfdpar.f90
@@ -71,7 +71,7 @@ subroutine rfdpar1(be,rate,m)
cof=zero
cof(0)=one
do i=1,m
- cof(i)=half*cof(i-1)/float(i)
+ cof(i)=half*cof(i-1)/real(i,r_kind)
enddo
! Locate the m roots of this polynomial:
call zroots(cof,m,croot,polish)
diff --git a/src/gsi/satthin.F90 b/src/gsi/satthin.F90
index 02d19b198c..c093c4b1d5 100644
--- a/src/gsi/satthin.F90
+++ b/src/gsi/satthin.F90
@@ -134,6 +134,8 @@ module satthin
use obsmod, only: time_window_max
use constants, only: deg2rad,rearth_equator,zero,two,pi,half,one,&
rad2deg,r1000
+ use chemmod, only: laeroana_fv3smoke
+
implicit none
! set default to private
@@ -348,7 +350,7 @@ subroutine makegvals
end subroutine makegvals
- subroutine makegrids(rmesh,ithin,n_tbin)
+ subroutine makegrids(rmesh,ithin,n_tbin,itxmax_in)
!$$$ subprogram documentation block
! . . . .
! subprogram: makegrids
@@ -384,7 +386,8 @@ subroutine makegrids(rmesh,ithin,n_tbin)
real(r_kind) ,intent(in ) :: rmesh
integer(i_kind),intent(in ) :: ithin
- integer(i_kind),intent(in ), optional :: n_tbin
+ integer(i_kind),intent(in ), optional :: n_tbin
+ integer(i_kind),intent(in ), optional :: itxmax_in
real(r_kind),parameter:: r360 = 360.0_r_kind
integer(i_kind) i,j
integer(i_kind) mlonx,mlonj
@@ -400,7 +403,11 @@ subroutine makegrids(rmesh,ithin,n_tbin)
itx_all=0
if(abs(rmesh) <= one .or. ithin <= 0)then
use_all=.true.
- itxmax=1e9
+ if (present(itxmax_in)) then
+ itxmax = itxmax_in
+ else
+ itxmax = 1e7
+ endif
allocate(icount(itxmax))
allocate(score_crit(itxmax))
do j=1,itxmax
@@ -612,9 +619,9 @@ subroutine getsfc(mype,mype_io,use_sfc,use_sfc_any)
jmax=nlat_sfc-2
allocate(slatx(jmax),wlatx(jmax))
call splat(idrt,jmax,slatx,wlatx)
- dlon=two*pi/float(nlon_sfc)
+ dlon=two*pi/real(nlon_sfc,r_kind)
do i=1,nlon_sfc
- rlons_sfc(i)=float(i-1)*dlon
+ rlons_sfc(i)=real(i-1,r_kind)*dlon
end do
do i=1,(nlat_sfc-1)/2
rlats_sfc(i+1)=-asin(slatx(i))
@@ -961,7 +968,10 @@ subroutine getsfc(mype,mype_io,use_sfc,use_sfc_any)
end if
if (.not.lobserver) then
if(allocated(veg_frac)) deallocate(veg_frac)
- if(allocated(veg_type)) deallocate(veg_type)
+! veg_type will be used in setuppm2_5.f90 for rrfs_sd PM2.5 DA
+ if(.not. laeroana_fv3smoke )then
+ if(allocated(veg_type)) deallocate(veg_type)
+ endif
if(allocated(soil_type)) deallocate(soil_type)
if(allocated(soil_moi)) deallocate(soil_moi)
if(allocated(sfc_rough)) deallocate(sfc_rough)
diff --git a/src/gsi/setupaod.f90 b/src/gsi/setupaod.f90
index a1e4656e76..e0964ee972 100644
--- a/src/gsi/setupaod.f90
+++ b/src/gsi/setupaod.f90
@@ -61,7 +61,8 @@ subroutine setupaod(obsLL,odiagLL,lunin,mype,nchanl,nreal,nobs,&
dplat,lobsdiagsave,lobsdiag_allocated,&
dirname,time_offset,luse_obsdiag
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d, nc_diag_chaninfo_dim_set, nc_diag_chaninfo
+ nc_diag_write, nc_diag_data2d, nc_diag_chaninfo_dim_set, nc_diag_chaninfo, &
+ nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim, nc_diag_read_close
use gsi_4dvar, only: nobs_bins,hr_obsbin
use gridmod, only: nsig,get_ij
@@ -179,6 +180,7 @@ subroutine setupaod(obsLL,odiagLL,lunin,mype,nchanl,nreal,nobs,&
real(r_kind) :: qcall, smask
real(r_kind) :: styp, dbcf
+ real(r_kind),dimension(nchanl):: chan_level
real(r_kind),dimension(nchanl):: emissivity,ts,emissivity_k
real(r_kind),dimension(nchanl):: tsim
real(r_kind),dimension(nsig,nchanl):: wmix,temp,ptau5
@@ -408,7 +410,7 @@ subroutine setupaod(obsLL,odiagLL,lunin,mype,nchanl,nreal,nobs,&
call call_crtm(obstype,dtime,data_s(:,n),nchanl,nreal,ich, &
tvp,qvp,qsat,clw_guess,ciw_guess,rain_guess,snow_guess,prsltmp,prsitmp, &
trop5,tzbgr,dtsavg,sfc_speed, &
- tsim,emissivity,ptau5,ts,emissivity_k, &
+ tsim,emissivity,chan_level,ptau5,ts,emissivity_k, &
temp,wmix,jacobian,error_status,layer_od=layer_od,jacobian_aero=jacobian_aero)
! interpolate aerosols at observation locations for diag files here
if (aero_diagsave) then
@@ -841,16 +843,16 @@ subroutine contents_netcdf_diag_
if ( iuse_aero(l) < 0 ) cycle
call nc_diag_metadata("Channel_Index", i)
call nc_diag_metadata("Observation_Class", obsclass)
- call nc_diag_metadata("Latitude", sngl(cenlat)) ! observation latitude (degrees)
- call nc_diag_metadata("Longitude", sngl(cenlon)) ! observation longitude (degrees)
- call nc_diag_metadata("Obs_Time", sngl(dtime))!-time_offset)) ! observation time (hours relative to analysis time)
- call nc_diag_metadata("Sol_Zenith_Angle", sngl(pangs)) ! solar zenith angle (degrees)
- call nc_diag_metadata("Sol_Azimuth_Angle", sngl(data_s(isazi_ang,n))) ! solar azimuth angle (degrees)
+ call nc_diag_metadata_to_single("Latitude",(cenlat)) ! observation latitude (degrees)
+ call nc_diag_metadata_to_single("Longitude",(cenlon)) ! observation longitude (degrees)
+ call nc_diag_metadata_to_single("Time",(dtime))!-time_offset)) ! observation time (hours relative to analysis time)
+ call nc_diag_metadata_to_single("Sol_Zenith_Angle",(pangs)) ! solar zenith angle (degrees)
+ call nc_diag_metadata_to_single("Sol_Azimuth_Angle",(data_s(isazi_ang,n))) ! solar azimuth angle (degrees)
call nc_diag_metadata("Surface_type", nint(data_s(istyp,n)))
call nc_diag_metadata("MODIS_deep_blue_flag", nint(dbcf) )
- call nc_diag_metadata("Observation", sngl(diagbufchan(1,i)) ) ! observed aod
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted",sngl(diagbufchan(2,i)))
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted",sngl(diagbufchan(2,i)))! obs - sim aod with no bias correction
+ call nc_diag_metadata("Observation",(diagbufchan(1,i)) ) ! observed aod
+ call nc_diag_metadata("Obs_Minus_Forecast_adjusted",(diagbufchan(2,i)))
+ call nc_diag_metadata("Obs_Minus_Forecast_unadjusted",(diagbufchan(2,i)))! obs - sim aod with no bias correction
if (diagbufchan(3,i) > tiny_r_kind) then
tmp(1)=one/diagbufchan(3,i)
@@ -859,7 +861,7 @@ subroutine contents_netcdf_diag_
end if
call nc_diag_metadata("Observation_Error",tmp(1))
- call nc_diag_metadata("QC_Flag", sngl(diagbufchan(4,i))) !quality control mark or event indicator
+ call nc_diag_metadata("QC_Flag",(diagbufchan(4,i))) !quality control mark or event indicator
tmp(1)=get_zsfc()
call nc_diag_metadata("sfc_height",tmp(1)) ! height in meters
diff --git a/src/gsi/setupbend.f90 b/src/gsi/setupbend.f90
index 9bc856d67a..074bc7e002 100644
--- a/src/gsi/setupbend.f90
+++ b/src/gsi/setupbend.f90
@@ -147,13 +147,17 @@ subroutine setupbend(obsLL,odiagLL, &
use gsi_4dvar, only: nobs_bins,hr_obsbin
use guess_grids, only: ges_lnprsi,hrdifsig,geop_hgti,nfldsig
+ use guess_grids, only: ges_lnprsl,ges_prsi,geop_hgtl
use guess_grids, only: nsig_ext,gpstop,commgpstop,commgpserrinf
+!> xuanli
+ use guess_grids, only: ges_tsen
+!< xuanli
use gridmod, only: nsig
use gridmod, only: get_ij,latlon11
use constants, only: fv,n_a,n_b,n_c,deg2rad,tiny_r_kind,r0_01,r18,r61,r63,r10000
use constants, only: zero,half,one,two,eccentricity,semi_major_axis,&
grav_equator,somigliana,flattening,grav_ratio,grav,rd,eps,three,four,five,&
- r100,r400
+ r100,r400,r1000
use lagmod, only: setq, setq_TL
use lagmod, only: slagdw, slagdw_TL
use jfunc, only: jiter,miter,jiterstart
@@ -225,10 +229,14 @@ subroutine setupbend(obsLL,odiagLL, &
real(r_kind),dimension(nele,nobs):: data
real(r_kind),dimension(nsig):: dbenddn,dbenddxi
real(r_kind) pressure,hob_s,d_ref_rad,d_ref_rad_TL,hob_s_top
+ real(r_kind) hobb
real(r_kind),dimension(4) :: w4,dw4,dw4_TL
-
+
+!> xuanli
integer(i_kind) ier,ilon,ilat,ihgt,igps,itime,ikx,iuse, &
- iprof,ipctc,iroc,isatid,iptid,ilate,ilone,ioff,igeoid
+ iprof,ipctc,iroc,isatid,iptid,ilate,ilone,ioff,igeoid,iqfro
+ integer(i_kind) iascd, iazm, iconstid, isiid, iogce, iref, ihggt
+!< xuanli
integer(i_kind) i,j,k,kk,mreal,nreal,jj,ikxx,ibin
integer(i_kind) mm1,nsig_up,ihob,istatus,nsigstart
integer(i_kind) kprof,istat,k1,k2,nobs_out,top_layer_SR,bot_layer_SR,count_SR
@@ -264,6 +272,11 @@ subroutine setupbend(obsLL,odiagLL, &
real(r_kind),allocatable,dimension(:,:,:,:) :: ges_tv
real(r_kind),allocatable,dimension(:,:,:,:) :: ges_q
+!> xuanli
+ real(r_kind),dimension(nsig, nobs) :: Tsen,Tvir,sphm,hgtl,prslnl
+ real(r_kind),dimension(nsig+1,nobs) :: hgti,prslni
+!< xuanli
+
type(obsLList),pointer,dimension(:):: gpshead
logical:: commdat
gpshead => obsLL(:)
@@ -301,7 +314,6 @@ subroutine setupbend(obsLL,odiagLL, &
!268 => PlanetiQ GNOMES-B
!269 => Spire Lemur 3U CubeSat
!66 => Sentinel-6
-
! Check to see if required guess fields are available
call check_vars_(proceed)
if(.not.proceed) return ! not all vars available, simply return
@@ -328,12 +340,22 @@ subroutine setupbend(obsLL,odiagLL, &
ilone=14 ! index of earth relative longitude (degrees)
ilate=15 ! index of earth relative latitude (degrees)
igeoid=16 ! index of geoid undulation (a value per profile, m)
+!> xuanli
+ iqfro=17 ! index of qfro (integer)
+ iascd=18 ! index of ascending flag (integer)
+ iazm=19 ! index of azimuth angle
+ iconstid=20 ! index of classification ID (integer)
+ isiid=21 ! index of occulting sat (integer)
+ iogce=22 ! index of identification of originating (integer)
+ iref=23 ! index of refractivity
+ ihggt=24 ! index of height
+!< xuanli
! Intialize variables
nsig_up=nsig+nsig_ext ! extend nsig_ext levels above interface level nsig
- rsig=float(nsig)
+ rsig=real(nsig,r_kind)
rdog=rd/grav
- rsig_up=float(nsig_up)
+ rsig_up=real(nsig_up,r_kind)
nobs_out=0
hob_s_top=one
mm1=mype+1
@@ -345,7 +367,8 @@ subroutine setupbend(obsLL,odiagLL, &
allocate(ddnj(grids_dim),grid_s(grids_dim),ref_rad_s(grids_dim))
! Allocate arrays for output to diagnostic file
- mreal=22
+! mreal=22 ! xuanli
+ mreal=35 ! xuanli
nreal=mreal
if (lobsdiagsave) nreal=nreal+4*miter+1
if (save_jacobian) then
@@ -453,6 +476,19 @@ subroutine setupbend(obsLL,odiagLL, &
prsltmp_o(1:nsig,i)=prsltmp(1:nsig) ! needed in minimization
+ call tintrp2a1(ges_tsen, Tsen(1:nsig,i), dlat,dlon,dtime,hrdifsig, &
+ nsig, mype,nfldsig)
+ call tintrp2a1(geop_hgtl, hgtl(1:nsig,i), dlat,dlon,dtime,hrdifsig, &
+ nsig, mype,nfldsig)
+ call tintrp2a1(ges_lnprsl,prslnl(1:nsig,i),dlat,dlon,dtime,hrdifsig, &
+ nsig, mype,nfldsig)
+
+ Tvir(1:nsig,i) = tges(1:nsig) ! virtual temperature
+ sphm(1:nsig,i) = qges(1:nsig) ! specific humidity
+ hgtl(1:nsig,i) = hgtl(1:nsig,i) + zsges ! mid level geopotential height
+ hgti(1:nsig+1,i) = hges(1:nsig+1) + zsges ! interface level geopotential height
+ prslni(1:nsig+1,i) = prsltmp(1:nsig+1) ! interface level log(pressure)
+
! Compute refractivity index-radius product at interface
!
! Convert geopotential height at layer midpoints to geometric height using
@@ -573,7 +609,11 @@ subroutine setupbend(obsLL,odiagLL, &
rdiagbuf(2,i) = data(iprof,i) ! profile identifier
rdiagbuf(3,i) = data(ilate,i) ! lat in degrees
rdiagbuf(4,i) = data(ilone,i) ! lon in degrees
- rdiagbuf(7,i) = tpdpres(i)-rocprof ! impact height in meters
+!> xuanli: modified imph in the diag file. In jedi: imph=impp-roc-geoid
+! rdiagbuf(7,i) = tpdpres(i)-rocprof ! impact height in meters
+ rdiagbuf(7,i) = tpdpres(i)-rocprof-unprof ! impact height in meters
+!< xuanli
+
! rdiagbuf(7,i) = tpdpres(i) ! impact parameter in meters
rdiagbuf(8,i) = dtime-time_offset ! obs time (hours relative to analysis time)
! rdiagbuf(9,i) = data(ipctc,i) ! input bufr qc - index of per cent confidence
@@ -582,6 +622,21 @@ subroutine setupbend(obsLL,odiagLL, &
rdiagbuf(17,i) = data(igps,i) ! bending angle observation (radians)
rdiagbuf(19,i) = hob ! model vertical grid (interface) if monotone grid
rdiagbuf(22,i) = 1.e+10_r_kind ! spread (filled in by EnKF)
+!> xuanli
+ rdiagbuf(23,i) = tpdpres(i) ! impact parameter in meters
+ rdiagbuf(24,i) = data(ipctc,i) ! input bufr qc - index of per cent confidence
+ rdiagbuf(25,i) = data(iptid,i) ! transmitter occ id
+ rdiagbuf(26,i) = rocprof ! local radius of curvature (m)
+ rdiagbuf(27,i) = unprof ! geoid undulation (m)
+ rdiagbuf(28,i) = data(iqfro,i) ! qfro
+ rdiagbuf(29,i) = data(iascd,i) ! ascending flag
+ rdiagbuf(30,i) = data(iazm,i) ! azimuth angle
+ rdiagbuf(31,i) = data(iconstid,i) ! satellite classification
+ rdiagbuf(32,i) = data(isiid,i) ! occulting satellite
+ rdiagbuf(33,i) = data(iogce,i) ! Identification of processing center
+ rdiagbuf(34,i) = data(iref,i) ! refractivity
+ rdiagbuf(35,i) = data(ihggt,i) ! geometric height
+!< xuanli -
if(ratio_errors(i) > tiny_r_kind) then ! obs inside model grid
@@ -618,14 +673,16 @@ subroutine setupbend(obsLL,odiagLL, &
ihob=hob
k1=min(max(1,ihob),nsig)
k2=max(1,min(ihob+1,nsig))
- delz=hob-float(k1)
+ delz=hob-real(k1,r_kind)
delz=max(zero,min(delz,one))
trefges=tges_o(k1,i)*(one-delz)+tges_o(k2,i)*delz
qrefges=qges_o(k1)*(one-delz)+qges_o(k2)*delz !Lidia
rdiagbuf( 6,i) = ten*exp(dpressure) ! pressure at obs location (hPa) if monotone grid
+ ! atmosphere_pressure_coordinate
rdiagbuf(18,i) = trefges ! temperature at obs location (Kelvin) if monotone grid
rdiagbuf(21,i) = qrefges ! specific humidity at obs location (kg/kg) if monotone grid
+
commdat=.false.
if (data(isatid,i)>=265 .and. data(isatid,i)<=269) commdat=.true.
if (.not. qcfail(i)) then ! not SR
@@ -715,7 +772,7 @@ subroutine setupbend(obsLL,odiagLL, &
call setq(q_w(:,k),ref_rad(k-1:k+1),3)
enddo
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter
! Get refractivity index-radius and [d(ln(n))/dx] in new grid.
intloop: do j=1,grids_dim
@@ -1027,6 +1084,28 @@ subroutine setupbend(obsLL,odiagLL, &
gps_alltail(ibin)%head%elat= data(ilate,i)
gps_alltail(ibin)%head%elon= data(ilone,i)
+! 2 dimensional geovals for JEDI
+ allocate(gps_alltail(ibin)%head%tvirges(nsig),stat=istatus)
+ allocate(gps_alltail(ibin)%head%tsenges(nsig),stat=istatus)
+ allocate(gps_alltail(ibin)%head%sphmges(nsig),stat=istatus)
+ allocate(gps_alltail(ibin)%head%hgtlges(nsig),stat=istatus)
+ allocate(gps_alltail(ibin)%head%hgtiges(nsig+1),stat=istatus)
+ allocate(gps_alltail(ibin)%head%prsiges(nsig+1),stat=istatus)
+ allocate(gps_alltail(ibin)%head%prslges(nsig),stat=istatus)
+
+ do j= 1, nsig
+ gps_alltail(ibin)%head%tvirges(j) = Tvir(j,i)
+ gps_alltail(ibin)%head%tsenges(j) = Tsen(j,i)
+ gps_alltail(ibin)%head%sphmges(j) = sphm(j,i)
+ gps_alltail(ibin)%head%hgtlges(j) = hgtl(j,i)
+ gps_alltail(ibin)%head%prslges(j) = 1000.0*exp(prslnl(j,i))
+ end do
+
+ do j= 1, nsig + 1
+ gps_alltail(ibin)%head%hgtiges(j) = hgti(j,i)
+ gps_alltail(ibin)%head%prsiges(j) = 1000.0*exp(prslni(j,i))
+ end do
+
allocate(gps_alltail(ibin)%head%rdiag(nreal),stat=istatus)
if (istatus/=0) write(6,*)'SETUPBEND: allocate error for gps_alldiag, istatus=',istatus
diff --git a/src/gsi/setupcldch.f90 b/src/gsi/setupcldch.f90
index cd3790016d..0cfda9a279 100644
--- a/src/gsi/setupcldch.f90
+++ b/src/gsi/setupcldch.f90
@@ -196,7 +196,7 @@ subroutine setupcldch(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_dia
isprvd=18 ! index of subprovider
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! Check for missing data !need obs value and error
diff --git a/src/gsi/setupcldtot.F90 b/src/gsi/setupcldtot.F90
index 3d899d1a82..694c8f1df3 100755
--- a/src/gsi/setupcldtot.F90
+++ b/src/gsi/setupcldtot.F90
@@ -45,13 +45,22 @@ subroutine setupcldtot(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_di
use mpeu_util, only: die,perr
use kinds, only: r_kind,r_single,r_double,i_kind
+ use constants, only: zero,one,r1000,r10,r100
+ use constants, only: huge_single,wgtlim,three
+ use constants, only: tiny_r_kind,five,half,two,r0_01
+ use constants, only: zero,one, h1000
+
use obsmod, only: rmiss_single,time_offset
+ use obsmod, only: netcdf_diag, binary_diag, dirname, ianldate
+ use obsmod, only: luse_obsdiag
+ use m_obsLList, only: obsLList
+ use m_obsdiagNode, only: obs_diags
use m_obsNode, only: obsNode
use m_qNode, only: qNode
use m_qNode, only: qNode_appendto
+ use m_dtime, only: dtime_setup, dtime_check, dtime_show
use gsi_4dvar, only: nobs_bins,hr_obsbin
- use obsmod, only: netcdf_diag, binary_diag, dirname, ianldate
use nc_diag_write_mod,only: nc_diag_init, nc_diag_header,nc_diag_metadata, &
nc_diag_write, nc_diag_data2d
use nc_diag_read_mod, only: nc_diag_read_init,nc_diag_read_get_dim, &
@@ -60,26 +69,18 @@ subroutine setupcldtot(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_di
use guess_grids, only: geop_hgtl,hrdifsig,nfldsig,ges_tsen,ges_prsl
use gridmod, only: nsig,get_ijk
- use constants, only: zero,one,r1000,r10,r100
- use constants, only: huge_single,wgtlim,three
- use constants, only: tiny_r_kind,five,half,two,r0_01
use qcmod, only: npres_print
use jfunc, only: jiter
use convinfo, only: nconvtype
use convinfo, only: icsubtype
- use m_dtime, only: dtime_setup, dtime_check, dtime_show
use rapidrefresh_cldsurf_mod, only: i_cloud_q_innovation, &
cld_bld_hgt,i_ens_mean
use gsi_bundlemod, only : gsi_bundlegetpointer
use gsi_metguess_mod, only : gsi_metguess_get,gsi_metguess_bundle
use mpimod, only: mpi_comm_world
- use constants, only: zero,one, h1000
use gsdcloudlib_pseudoq_mod, only: cloudLWC_pseudo,cloudCover_Surface_col
- use m_obsLList, only: obsLList
- use m_obsdiagNode, only: obs_diags
- use obsmod, only: luse_obsdiag
implicit none
@@ -90,7 +91,7 @@ subroutine setupcldtot(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_di
integer(i_kind) ,intent(in ) :: lunin,mype,nele,nobs
real(r_kind),dimension(100+7*nsig) ,intent(inout) :: awork
real(r_kind),dimension(npres_print,nconvtype,5,3),intent(inout) :: bwork
- integer(i_kind) ,intent(in ) :: is ! ndat index
+ integer(i_kind) ,intent(in ) :: is ! ndat index
logical ,intent(in ) :: conv_diagsave
#ifdef RR_CLOUDANALYSIS
diff --git a/src/gsi/setupdbz.f90 b/src/gsi/setupdbz.f90
index 9bbf5ed34b..4f25256c98 100644
--- a/src/gsi/setupdbz.f90
+++ b/src/gsi/setupdbz.f90
@@ -131,7 +131,7 @@ subroutine setupdbz(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,radardbz_d
use obsmod, only: luse_obsdiag, netcdf_diag, binary_diag, dirname, ianldate
use obsmod, only: doradaroneob,oneobddiff,oneobvalue
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim,nc_diag_read_close
use oneobmod, only: oneobtest
use oneobmod, only: maginnov
@@ -150,7 +150,7 @@ subroutine setupdbz(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,radardbz_d
use convinfo, only: nconvtype,cermin,cermax,cgross,cvar_b,cvar_pg,ictype
use convinfo, only: icsubtype
use m_dtime, only: dtime_setup, dtime_check
- use obsmod, only : if_model_dbz, inflate_obserr
+ use obsmod, only : if_model_dbz, inflate_dbz_obserr
use setupdbz_lib, only:hx_dart,jqr_dart,jqs_dart,jqg_dart
use gridmod, only: wrf_mass_regional,nems_nmmb_regional, fv3_regional
use sparsearr, only: sparr2, new, size, writearray, fullarray
@@ -364,7 +364,7 @@ subroutine setupdbz(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,radardbz_d
iptrb=26 ! index of dbz perturbation
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
if ( .not. luse(i) ) then
icnt_nouse = icnt_nouse + 1
@@ -426,6 +426,7 @@ subroutine setupdbz(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,radardbz_d
if (lobsdiagsave) nreal=nreal+4*miter+1
if (.not.allocated(cdiagbuf)) allocate(cdiagbuf(nobs))
if (.not.allocated(rdiagbuf)) allocate(rdiagbuf(nreal,nobs))
+ if(netcdf_diag) call init_netcdf_diag_
end if
mm1=mype+1
scale=one
@@ -589,14 +590,17 @@ subroutine setupdbz(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,radardbz_d
! Compute observation pressure (only used for diagnostics)
dz = zges(k2)-zges(k1)
dlnp = prsltmp(k2)-prsltmp(k1)
- pobl = prsltmp(k1) + (dlnp/dz)*(zob-zges(k1))
-
- presw = ten*exp(pobl)
-
if ( l_use_dbz_directDA ) then
- presq = presw
+ pobl = prsltmp(k1) + (dlnp/dz)*(zob-zges(k1))
+ presw = ten*exp(pobl)
+ presq = presw
else
- if( (k1 == k2) .and. (k1 == 1) ) presw=ten*exp(prsltmp(k1))
+ if( (k1 == k2) .and. (k1 == 1) ) then
+ presw = ten*exp(prsltmp(k1))
+ else
+ pobl = prsltmp(k1) + (dlnp/dz)*(zob-zges(k1))
+ presw = ten*exp(pobl)
+ end if
end if
! solution to Nan in some members only for EnKF which causes problem?
@@ -1256,8 +1260,11 @@ subroutine setupdbz(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,radardbz_d
end if
else
- if (ratio > cgross(ikx) .or. ratio_errors < tiny_r_kind) then
- if ( inflate_obserr .and. (ratio-cgross(ikx)) <= cgross(ikx) .and. ratio_errors >= tiny_r_kind) then
+
+! Apply gross error check only to reflectivity observations in precipitation (>= 5 dBZ).
+ if ( ( (data(idbzob,i) >= 5_r_kind) .and. (ratio > cgross(ikx)) ) .or. (ratio_errors < tiny_r_kind) ) then
+
+ if ( inflate_dbz_obserr .and. (ratio-cgross(ikx)) <= cgross(ikx) .and. ratio_errors >= tiny_r_kind) then
! Since radar reflectivity can be very different from the model background
! good observations may be rejected during this QC step. However, if these observations
! are allowed through, they can yield problems with convergence. Therefore the error
@@ -1447,35 +1454,42 @@ subroutine setupdbz(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,radardbz_d
! Release memory of local guess arrays
call final_vars_
-
! Write information to diagnostic file
- if(radardbz_diagsave .and. ii>0 )then
+ if(radardbz_diagsave .and. netcdf_diag) call nc_diag_write
+ if(radardbz_diagsave .and. binary_diag .and. ii>0 )then
- write(string,600) jiter
-600 format('radardbz_',i2.2)
- diag_file=trim(dirname) // trim(string)
- if(init_pass) then
- open(newunit=lu_diag,file=trim(diag_file),form='unformatted',status='unknown',position='rewind')
+ if( .not. l_use_dbz_directDA .and. .not. if_model_dbz )then
+ write(7)'dbz',nchar,nreal,ii,mype,ioff0
+ write(7)cdiagbuf(1:ii),rdiagbuf(:,1:ii)
+ deallocate(cdiagbuf,rdiagbuf)
else
- inquire(file=trim(diag_file),exist=diagexist)
- if (diagexist) then
- open(lu_diag,file=trim(diag_file),form='unformatted',status='old',position='append')
+
+ write(string,600) jiter
+600 format('radardbz_',i2.2)
+ diag_file=trim(dirname) // trim(string)
+ if(init_pass) then
+ open(newunit=lu_diag,file=trim(diag_file),form='unformatted',status='unknown',position='rewind')
else
- open(lu_diag,file=trim(diag_file),form='unformatted',status='unknown',position='rewind')
+ inquire(file=trim(diag_file),exist=diagexist)
+ if (diagexist) then
+ open(lu_diag,file=trim(diag_file),form='unformatted',status='old',position='append')
+ else
+ open(lu_diag,file=trim(diag_file),form='unformatted',status='unknown',position='rewind')
+ endif
+ endif
+ if(init_pass .and. mype == 0) then
+ if ( .not. l_use_dbz_directDA ) then ! EnKF uses these diagnostics and EnKF uses single OBS file for now.
+ write(lu_diag) ianldate ! So do not write analysis date for binary in case of using direct reflectivity DA.
+ end if
+ write(6,*)'SETUPDBZ: write time record to file ',&
+ trim(diag_file), ' ',ianldate
endif
- endif
- if(init_pass .and. mype == 0) then
- if ( .not. l_use_dbz_directDA ) then ! EnKF uses these diagnostics and EnKF uses single OBS file for now.
- write(lu_diag) ianldate ! So do not write analysis date for binary in case of using direct reflectivity DA.
- end if
- write(6,*)'SETUPDBZ: write time record to file ',&
- trim(diag_file), ' ',ianldate
- endif
- write(lu_diag)'dbz',nchar,nreal,ii,mype,ioff0
- write(lu_diag)cdiagbuf(1:ii),rdiagbuf(:,1:ii)
- deallocate(cdiagbuf,rdiagbuf)
- close(lu_diag)
+ write(lu_diag)'dbz',nchar,nreal,ii,mype,ioff0
+ write(lu_diag)cdiagbuf(1:ii),rdiagbuf(:,1:ii)
+ deallocate(cdiagbuf,rdiagbuf)
+ close(lu_diag)
+ end if
end if
write(6,*)'mype, irefsmlobs,irejrefsmlobs are ',mype,' ',irefsmlobs, ' ',irejrefsmlobs
! close(52) !simulated obs
@@ -1773,7 +1787,7 @@ subroutine init_netcdf_diag_
end if
call nc_diag_init(diag_conv_file, append=append_diag)
-
+
if (.not. append_diag) then ! don't write headers on append - the module will break?
call nc_diag_header("date_time",ianldate )
call nc_diag_header("Number_of_state_vars", nsdim )
@@ -1920,29 +1934,29 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_metadata("Observation_Class", obsclass )
call nc_diag_metadata("Observation_Type", ictype(ikx) )
call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
- call nc_diag_metadata("Station_Elevation", sngl(data(ielev,i)) )
- call nc_diag_metadata("Pressure", sngl(presw) )
- call nc_diag_metadata("Height", sngl(data(ihgt,i)) )
- call nc_diag_metadata("Time", sngl(dtime-time_offset))
- call nc_diag_metadata("Prep_QC_Mark", sngl(zero) )
- call nc_diag_metadata("Prep_Use_Flag", sngl(data(iuse,i)) )
+ call nc_diag_metadata_to_single("Latitude", data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude", data(ilone,i) )
+ call nc_diag_metadata_to_single("Station_Elevation",data(ielev,i) )
+ call nc_diag_metadata_to_single("Pressure", presw )
+ call nc_diag_metadata_to_single("Height", data(ihgt,i) )
+ call nc_diag_metadata_to_single("Time", dtime, time_offset, "-")
+ call nc_diag_metadata_to_single("Prep_QC_Mark", zero )
+ call nc_diag_metadata_to_single("Prep_Use_Flag", data(iuse,i) )
! call nc_diag_metadata("Nonlinear_QC_Var_Jb", var_jb ! )
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",rwgt )
if(muse(i)) then
- call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
+ call nc_diag_metadata_to_single("Analysis_Use_Flag",one )
else
- call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
+ call nc_diag_metadata_to_single("Analysis_Use_Flag",-one )
endif
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
+ call nc_diag_metadata_to_single("Errinv_Input", errinv_input )
+ call nc_diag_metadata_to_single("Errinv_Adjust", errinv_adjst )
+ call nc_diag_metadata_to_single("Errinv_Final", errinv_final )
- call nc_diag_metadata("Observation", sngl(data(idbzob,i)) )
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ddiff) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(data(idbzob,i)-rdBZ) )
+ call nc_diag_metadata_to_single("Observation", data(idbzob,i) )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",ddiff )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted", data(idbzob,i), rdBZ, "-")
if (lobsdiagsave) then
do jj=1,miter
diff --git a/src/gsi/setupdw.f90 b/src/gsi/setupdw.f90
index 93749b2ad9..6ca68e4cae 100644
--- a/src/gsi/setupdw.f90
+++ b/src/gsi/setupdw.f90
@@ -37,7 +37,7 @@ subroutine setupdw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsa
use obsmod, only: rmiss_single,lobsdiag_forenkf
use obsmod, only: netcdf_diag, binary_diag, dirname, ianldate
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim, nc_diag_read_close
use m_obsdiagNode, only: obs_diag
use m_obsdiagNode, only: obs_diags
@@ -298,7 +298,7 @@ subroutine setupdw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsa
end if
scale=one
- rsig=float(nsig)
+ rsig=real(nsig,r_kind)
mm1=mype+1
call dtime_setup()
@@ -496,7 +496,7 @@ subroutine setupdw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsa
dwwind=(ugesindw*sinazm+vgesindw*cosazm)*factw
iz = max(1, min( int(dpres), nsig))
- delz = max(zero, min(dpres - float(iz), one))
+ delz = max(zero, min(dpres - real(iz,r_kind), one))
if (save_jacobian) then
u_ind = getindex(svars3d, 'u')
@@ -904,29 +904,29 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_metadata("Observation_Class", obsclass )
call nc_diag_metadata("Observation_Type", ictype(ikx) )
call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
+ call nc_diag_metadata_to_single("Latitude", data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude", data(ilone,i) )
call nc_diag_metadata("Station_Elevation", missing )
- call nc_diag_metadata("Pressure", sngl(presw) )
- call nc_diag_metadata("Height", sngl(data(ihgt,i)) )
- call nc_diag_metadata("Time", sngl(dtime-time_offset))
+ call nc_diag_metadata_to_single("Pressure", presw )
+ call nc_diag_metadata_to_single("Height", data(ihgt,i) )
+ call nc_diag_metadata_to_single("Time", dtime,time_offset,"-" )
call nc_diag_metadata("Prep_QC_Mark", missing )
- call nc_diag_metadata("Prep_Use_Flag", sngl(data(iuse,i)) )
+ call nc_diag_metadata_to_single("Prep_Use_Flag", data(iuse,i) )
! call nc_diag_metadata("Nonlinear_QC_Var_Jb", var_jb )
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",rwgt )
if(muse(i)) then
- call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
+ call nc_diag_metadata_to_single("Analysis_Use_Flag",one )
else
- call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
+ call nc_diag_metadata_to_single("Analysis_Use_Flag",-one )
endif
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
+ call nc_diag_metadata_to_single("Errinv_Input",errinv_input )
+ call nc_diag_metadata_to_single("Errinv_Adjust",errinv_adjst )
+ call nc_diag_metadata_to_single("Errinv_Final",errinv_final )
- call nc_diag_metadata("Observation", sngl(data(ilob,i)))
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ddiff) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(data(ilob,i)-dwwind))
+ call nc_diag_metadata_to_single("Observation",data(ilob,i) )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",ddiff )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted", data(ilob,i), dwwind, '-')
!_RT_NC4_TODO
!_RT rdiagbuf(20,ii) = factw ! 10m wind reduction factor
diff --git a/src/gsi/setupfed.f90 b/src/gsi/setupfed.f90
new file mode 100644
index 0000000000..682c056adf
--- /dev/null
+++ b/src/gsi/setupfed.f90
@@ -0,0 +1,1129 @@
+module fed_setup
+ implicit none
+ private
+ public:: setup
+ interface setup; module procedure setupfed; end interface
+
+contains
+subroutine setupfed(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,fed_diagsave,init_pass)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: setupfed compute rhs of flash extent density
+! orig. prgmmr:
+! Rong Kong CAPS/OU 2018-01-21 (modified based on setupdbz.f90)
+! modified:
+! Yaping Wang CIMMS/OU 2019-11-11
+! David Dowell (DCD) NOAA GSL 2021-07-01
+! - added a second option (tanh) for observation operator, based on the
+! work of Sebok and Back (2021, unpublished)
+! - capped maximum model FED
+! Hongli Wang NOAA GSL 2023-09-14
+! - Add option to use fed from background file to calculate fed innov
+! - cleanup code, removed hardcoded obs height (6500m)
+!
+ use mpeu_util, only: die,perr
+ use kinds, only: r_kind,r_single,r_double,i_kind
+ use m_obsdiagNode, only: obs_diag
+ use m_obsdiagNode, only: obs_diags
+ use m_obsdiagNode, only: obsdiagLList_nextNode
+ use m_obsdiagNode, only: obsdiagNode_set
+ use m_obsdiagNode, only: obsdiagNode_get
+ use m_obsdiagNode, only: obsdiagNode_assert
+ use obsmod, only: rmiss_single,&
+ lobsdiagsave,nobskeep,lobsdiag_allocated,time_offset
+ use obsmod, only: oberror_tune
+ use obsmod, only: if_model_fed,innov_use_model_fed,dofedoneob,oneobddiff,oneobvalue
+ use m_obsNode, only: obsNode
+ use m_fedNode, only: fedNode
+ use m_fedNode, only: fedNode_appendto
+ use obsmod, only: luse_obsdiag, netcdf_diag, binary_diag, dirname, ianldate
+ use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
+ nc_diag_write, nc_diag_data2d
+ use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim,nc_diag_read_close
+ use m_obsLList, only: obsLList
+ use gsi_4dvar, only: nobs_bins,hr_obsbin
+ use oneobmod, only: magoberr
+ use guess_grids, only: hrdifsig,nfldsig,ges_prsi
+ use guess_grids, only: ges_lnprsl, geop_hgtl
+ use gridmod, only: lat2, lon2
+ use gridmod, only: nsig, get_ij,get_ijk,tll2xy
+ use constants, only: flattening,semi_major_axis,grav_ratio,zero,grav,wgtlim
+ use constants, only: half,one,two,grav_equator,eccentricity,somigliana
+ use constants, only: deg2rad,r60,tiny_r_kind,cg_term,huge_single
+ use constants, only: r10,r100,r1000
+ use constants, only: grav,tpwcon
+ use qcmod, only: npres_print,ptopq,pbotq
+ use jfunc, only: jiter,last,miter
+ use convinfo, only: nconvtype,cermin,cermax,cgross,cvar_b,cvar_pg,ictype
+ use convinfo, only: icsubtype
+ use converr, only: ptabl
+ use m_dtime, only: dtime_setup, dtime_check, dtime_show
+ use state_vectors, only: nsdim
+
+ use gsi_bundlemod, only: GSI_BundleGetPointer
+ use gsi_metguess_mod, only: gsi_metguess_get, GSI_MetGuess_Bundle
+
+ use netcdf
+
+
+ implicit none
+! Declare passed variables
+ type(obsLList ),target,dimension(:),intent(in):: obsLL
+ type(obs_diags),target,dimension(:),intent(in):: odiagLL
+
+ logical ,intent(in ) :: fed_diagsave
+ integer(i_kind) ,intent(in ) :: lunin,mype,nele,nobs
+ real(r_kind),dimension(100+7*nsig) ,intent(inout) :: awork
+ real(r_kind),dimension(npres_print,nconvtype,5,3),intent(inout) :: bwork
+ integer(i_kind) ,intent(in ) :: is ! ndat index
+ logical ,intent(in ) :: init_pass ! state of "setup" parameters
+
+
+! Declare local parameters
+ integer(i_kind),parameter:: fed_obs_ob_shape = 2 ! 1 = linear (Allen et al.)
+ ! 2 = tanh (Sebok and Back)
+! coefficients for tanh operator, from Sebok and Back (2021)
+! real(r_kind),parameter:: a_coeff = 8.4_r_kind ! a (flashes/min) in tanh operator
+! real(r_kind),parameter:: b_coeff = 12.248_r_kind ! b (flashes/min) in tanh operator
+! real(r_kind),parameter:: c_coeff = 5.0e-10_r_kind ! c (radians/kg) in tanh operator
+! real(r_kind),parameter:: d_coeff = 1.68e9_r_kind ! d (kg) in tanh operator
+! real(r_kind),parameter:: fed_highbnd = 18.0_r_kind ! DCD: Sebok and Back (2021, unpublished)
+
+! coefficients for tanh operator, from work by A. Back with regional FV3 (2023)
+ real(r_kind),parameter:: a_coeff = -3.645_r_kind ! a (flashes/min) in tanh operator
+ real(r_kind),parameter:: b_coeff = 15.75_r_kind ! b (flashes/min) in tanh operator
+ real(r_kind),parameter:: c_coeff = 1.939e-10_r_kind ! c (radians/kg) in tanh operator
+ real(r_kind),parameter:: d_coeff = -1.215e9_r_kind ! d (kg) in tanh operator
+ real(r_kind),parameter:: fed_highbnd = 8.0_r_kind ! DCD: Back (2023, unpublished) for FV3
+
+ real(r_kind),parameter:: r0_001 = 0.001_r_kind
+ real(r_kind),parameter:: r8 = 8.0_r_kind
+ real(r_kind),parameter:: ten = 10.0_r_kind
+ real(r_kind),parameter:: D608=0.608_r_kind
+ character(len=*),parameter:: myname='setupfed'
+
+! Declare external calls for code analysis
+ external:: tintrp2a1
+ external:: tintrp2a11
+ external:: tintrp2a1116
+ external:: tintrp31
+ external:: grdcrd1
+ external:: stop2
+
+! Declare local variables
+ real(r_kind) rlow,rhgh,rsig
+ real(r_kind) dz
+ real(r_kind) jqg_num,jqg
+ real(r_kind) dlnp,pobl,zob
+ real(r_kind) sin2,termg,termr,termrg
+ real(r_kind) psges,zsges
+ real(r_kind),dimension(nsig):: zges,hges
+ real(r_kind) prsltmp(nsig)
+ real(r_kind) sfcchk
+ real(r_kind) residual,obserrlm,obserror,ratio,scale,val2
+ real(r_kind) ress,ressw
+ real(r_kind) val,valqc,rwgt
+ real(r_kind) cg_w,wgross,wnotgross,wgt,arg,exp_arg,term,rat_err2
+ real(r_double) rstation_id
+ real(r_kind) dlat,dlon,dtime,dpres,ddiff,error,slat,dlat8km,dlon8km
+ real(r_kind) ratio_errors
+ real(r_kind) presw
+ real(r_kind) errinv_input,errinv_adjst,errinv_final
+ real(r_kind) err_input,err_adjst,err_final
+ real(r_kind),dimension(nele,nobs):: data
+ real(r_kind),dimension(lat2,lon2,nfldsig)::rp
+ real(r_single),allocatable,dimension(:,:)::rdiagbuf
+ real(r_kind),allocatable,dimension(:,:,: ) :: ges_z
+ real(r_kind),allocatable,dimension(:,:,: ) :: ges_ps
+ real(r_kind),allocatable,dimension(:,:,:,:) :: ges_q
+ real(r_kind),allocatable,dimension(:,:,:,:) :: ges_qg,ges_qg_mask
+ real(r_kind),allocatable,dimension(:,:,:,:) :: ges_fed
+ real(r_kind) :: presq
+ real(r_kind) :: T1D,RHO
+ real(r_kind) :: glmcoeff = 2.088_r_kind*10.0**(-8.0) ! Allen et al. (2016,MWR)
+ real(r_kind) :: CM = 0.5_r_kind ! tuning factor in eq. 14 of Kong et al. 2020
+
+ integer(i_kind) i,nchar,nreal,k,j,k1,ii,jj
+ integer(i_kind) mm1,k2
+ integer(i_kind) jsig,ikxx,nn,ibin,ioff,ioff0
+ integer(i_kind) ier,ilat,ilon,ifedob,ikx,itime,iuse
+ integer(i_kind) id,ilone,ilate
+ integer(i_kind) ier2
+
+ integer(i_kind) nlat_ll,nlon_ll,nsig_ll,nfld_ll
+
+ integer(i_kind) ipres,iqmax,iqc,icat,itemp
+ integer(i_kind) istnelv,iobshgt,izz,iprvd,isprvd,iptrb
+ integer(i_kind) idomsfc,iskint,isfcr,iff10
+
+ character(8) station_id
+ character(8),allocatable,dimension(:):: cdiagbuf
+ character(80):: string
+ character(128):: diag_file
+ logical :: diagexist
+ logical,dimension(nobs):: luse,muse
+ integer(i_kind),dimension(nobs):: ioid ! initial (pre-distribution) obs ID
+ logical proceed
+
+ equivalence(rstation_id,station_id)
+ integer(i_kind) numequal,numnotequal
+
+ type(fedNode),pointer:: my_head
+ type(obs_diag),pointer:: my_diag
+ type(obs_diags),pointer:: my_diagLL
+
+ real(r_kind),dimension(nsig+1):: prsitmp
+
+
+!------------------------------------------------!
+
+ integer(i_kind) :: itmp,jtmp
+
+ integer(i_kind), parameter :: ntimesfed=1
+ integer(i_kind),parameter :: nxfed=99, nyfed=99, nzfed=1, nfldfed=3
+ real(r_kind),dimension(nobs) :: FEDMdiag,FEDMdiagTL
+ integer(i_kind) :: npt
+ real(r_kind) :: dlat_earth,dlon_earth
+
+! YPW added the next lines
+ logical :: l_set_oerr_ratio_fed=.False.
+ logical :: l_gpht2gmht = .True.
+ real(r_kind),dimension(nobs) :: dlatobs,dlonobs
+ integer(i_kind):: ngx,ngy,igx,jgy
+ real(r_kind):: dx_m, dy_m
+
+ type(obsLList),pointer,dimension(:):: fedhead
+ fedhead => obsLL(:)
+
+!============================================================================================
+! Read and reformat observations in work arrays.
+ read(lunin)data,luse,ioid
+
+ write(6,*)myname,'(pe=',mype,') nele nobs =',nele,nobs, &
+ 'luse_obsdiag=',luse_obsdiag,'lat2,lon2=',lat2,lon2
+
+ ier=1 ! index of obs error
+ ilon=2 ! index of grid relative obs location (x)
+ ilat=3 ! index of grid relative obs location (y)
+ ipres=4 ! index of pressure
+ ifedob=5 ! index of fed observation
+ id=6 ! index of station id
+ itime=7 ! index of observation time in data array
+ ikxx=8 ! index of ob type
+ iqmax=9 ! index of max error
+ itemp=10 ! index of dry temperature
+ iqc=11 ! index of quality mark
+ ier2=12 ! index of original-original obs error ratio
+ iuse=13 ! index of use parameter
+ idomsfc=14 ! index of dominant surface type
+ iskint=15 ! index of surface skin temperature
+ iff10=16 ! index of 10 meter wind factor
+ isfcr=17 ! index of surface roughness
+ ilone=18 ! index of longitude (degrees)
+ ilate=19 ! index of latitude (degrees)
+ istnelv=20 ! index of station elevation (m)
+ iobshgt=21 ! index of observation height (m)
+ izz=22 ! index of surface height
+ iprvd=23 ! index of observation provider
+ isprvd=24 ! index of observation subprovider
+ icat =25 ! index of data level category
+ iptrb=26 ! index of fed perturbation
+ do i=1,nobs
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
+ end do
+
+ if (dofedoneob) then
+ muse=.true.
+ end if
+
+ numequal=0
+ numnotequal=0
+
+!
+! If requested, save select data for output to diagnostic file
+ if(fed_diagsave)then
+ ii=0
+ nchar=1_i_kind
+ ioff0=26_i_kind ! 21 + 5 (22->Zr; 23->Zs; 24->Zg; 25->tsenges;26->RHO;)
+ nreal=ioff0
+ if (lobsdiagsave) nreal=nreal+4*miter+1
+ allocate(cdiagbuf(nobs),rdiagbuf(nreal,nobs))
+ rdiagbuf=zero
+ if(netcdf_diag) call init_netcdf_diag_
+ end if
+ mm1=mype+1
+ scale=one
+ rsig=nsig
+
+
+
+ !============================================================================================
+!
+! Check to see if required guess fields are available
+! vars. list: ps, z, q
+! vars. list: qr, qs, qg
+ !============================================================================================
+
+ call check_vars_(proceed)
+ if(.not.proceed) then
+ write(6,*) myname,': some or all necessary variables are not available for fed obs operator. Quit!'
+ return ! not all vars available, simply return
+ end if
+
+! If require guess vars available, extract from bundle ...
+ call init_vars_
+! qscalar=zero
+
+ !============================================================================================
+ ! 1) Calculate the graupel-mass and graupel-volume based flash extent density
+ ! (FED) on model space, added by R. Kong, 07/05/2018
+ !============================================================================================
+ ges_qg_mask=ges_qg
+ where(ges_qg>0.0005) !Count the volume where qg > 0.5/kg
+ ges_qg_mask=1.0
+ elsewhere
+ ges_qg_mask=0.0
+ endwhere
+
+ ! Operator start here
+ ! set ngx and ngy =2, so the integrated domain is 15kmx15km
+ ngx = 2
+ ngy = 2
+ dx_m = 3000.
+ dy_m = 3000.
+ print*,'FED Operator start here!,ngx=',ngx,'ngy=',ngy
+ rp=zero
+
+ print*, 'mype = ', mype
+ print*, 'nfldsig = ', nfldsig
+ print*, 'nsig = ', nsig
+ print*, 'lon2 = ', lon2
+ print*, 'lat2 = ', lat2
+ if (.not. innov_use_model_fed .or. .not. if_model_fed) then
+! compute graupel mass, in kg per 15 km x 15 km column
+ do jj=1,nfldsig
+ do k=1,nsig
+ do i=1,lon2
+ do j=1,lat2 !How to handle MPI????
+ do igx=1,2*ngx+1 !horizontal integration of qg around point to calculate FED
+ do jgy=1,2*ngy+1
+ itmp = i-ngx+igx-1
+ jtmp = j-ngy+jgy-1
+ itmp = min(max(1,itmp),lon2)
+ jtmp = min(max(1,jtmp),lat2)
+ rp(j,i,jj)=rp(j,i,jj) + ges_qg(jtmp,itmp,k,jj)* &
+ dx_m*dy_m*(ges_prsi(jtmp,itmp,k,jj)-ges_prsi(jtmp,itmp,k+1,jj))*&
+ tpwcon * r10
+ end do !igx
+ end do !jgy
+ end do !j
+ end do !i
+ end do !k
+ end do !jj
+
+! compute FED, in flashes/min
+ do jj=1,nfldsig
+ do i=1,lon2
+ do j=1,lat2
+ if (fed_obs_ob_shape .eq. 1) then
+ rp(j,i,jj) = CM * glmcoeff * rp(j,i,jj)
+ else if (fed_obs_ob_shape .eq. 2) then
+ rp(j,i,jj) = a_coeff + b_coeff &
+ * tanh(c_coeff * (rp(j,i,jj) - d_coeff))
+ else
+ write(6,*) ' unknown fed_obs_ob_shape: ', fed_obs_ob_shape
+ write(6,*) ' aborting setupfed'
+ call stop2(999)
+ end if
+ if (rp(j,i,jj) .gt. fed_highbnd) rp(j,i,jj) = fed_highbnd
+ end do !j
+ end do !i
+ end do !jj
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ write(6,*) 'fed_obs_ob_shape=',fed_obs_ob_shape
+ if (fed_obs_ob_shape .eq. 2) then
+ write(6,*) 'a_coeff=',a_coeff
+ write(6,*) 'b_coeff=',b_coeff
+ write(6,*) 'c_coeff=',c_coeff
+ write(6,*) 'd_coeff=',d_coeff
+ end if
+ write(6,*) 'fed_highbnd=',fed_highbnd
+ write(6,*) 'maxval(ges_qg)=',maxval(ges_qg),'pe=',mype
+ end if ! .not. innov_use_model_fed .or. .not. if_model_fed
+
+ !============================================================================================
+
+ nlat_ll=size(ges_qg,1)
+ nlon_ll=size(ges_qg,2)
+ nsig_ll=size(ges_qg,3)
+ nfld_ll=size(ges_qg,4)
+
+ do i=1,nobs
+ dtime=data(itime,i)
+ dlat=data(ilat,i)
+ dlon=data(ilon,i)
+
+ dlon8km=data(iprvd,i) !iprvd=23
+ dlat8km=data(isprvd,i) !isprvd=24
+
+ dpres=data(ipres,i) ! from rdararef_mosaic2: this height abv MSL
+ ikx = nint(data(ikxx,i))
+ error=data(ier2,i)
+ slat=data(ilate,i)*deg2rad ! needed when converting geophgt to
+ dlon_earth = data(ilone,i) !the lontitude and latitude on the obs pts.
+ dlat_earth = data(ilate,i)
+ ! geometric hgh (hges --> zges below)
+
+ if (nobs_bins>1) then
+ ibin = NINT( dtime/hr_obsbin ) + 1
+ else
+ ibin = 1
+ end if
+
+ if (ibin<1.or.ibin>nobs_bins) write(6,*)mype,'Error nobs_bins,ibin= ',nobs_bins,ibin
+
+ if (luse_obsdiag) my_diagLL => odiagLL(ibin)
+
+! Link obs to diagnostics structure
+ if(luse_obsdiag)then
+ my_diag => obsdiagLList_nextNode(my_diagLL ,&
+ create = .not.lobsdiag_allocated ,&
+ idv = is ,&
+ iob = ioid(i) ,&
+ ich = 1 ,&
+ elat = data(ilate,i) ,&
+ elon = data(ilone,i) ,&
+ luse = luse(i) ,&
+ miter = miter )
+ if(.not.associated(my_diag)) call die(myname, &
+ 'obsdiagLList_nextNode(), create =',.not.lobsdiag_allocated)
+ end if
+
+! Interpolate terrain height(model elevation) to obs location.
+ call tintrp2a11(ges_z,zsges,dlat,dlon,dtime,hrdifsig,&
+ mype,nfldsig)
+! print*,'i,after tintrp2all',i,mype,dlat,zsges
+! 1. dpres (MRMS obs height is height above MSL) is adjusted by zsges, so it
+! is changed to height relative to model elevation (terrain).
+! because in GSI, geop_hgtl is the height relative to terrain (ges_z)
+! (subroutine guess_grids)
+ dpres=dpres-zsges
+ if (dpres rsig)ratio_errors = zero
+
+!----------------------------------------------------------------------------!
+! !
+! Implementation of forward operator for flash extend densit ----------------!
+! !
+!----------------------------------------------------------------------------!
+
+ !============================================================================================
+ ! 3) H(x), interpolate the FED from model space on the local domain to obs space (FEDMdiag)
+ !============================================================================================
+
+ npt = 0
+ FEDMdiag(i) = 0.
+ if (if_model_fed .and. innov_use_model_fed) then
+ !use fed from background file
+ call tintrp31(ges_fed,FEDMdiag(i), dlat,dlon,dpres,dtime,hrdifsig,mype,nfldsig)
+ else
+ call tintrp2a11(rp,FEDMdiag(i),dlat,dlon,dtime,hrdifsig,mype,nfldsig)
+ end if
+ dlonobs(i) = dlon_earth
+ dlatobs(i) = dlat_earth
+
+ ! also Jacobian used for TLM and ADM
+ !FEDMdiagTL, used for gsi-3dvar,will be implemented in future......
+ FEDMdiagTL(i) = 0.
+ jqg_num = FEDMdiagTL(i) !=dFED/Dqg
+ jqg = jqg_num
+
+
+ if(FEDMdiag(i)==data(ifedob,i)) then
+ numequal=numequal+1
+ else
+ numnotequal=numnotequal+1
+ end if
+
+!!!!!!!!!!!!!!!!!END H(x)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ ! Compute innovations
+ !--------------Calculate departure from observation----------------!
+
+ ddiff = data(ifedob,i) - FEDMdiag(i)
+ if (dofedoneob) then
+ !use magoberr to define obs error, but oneobtest=.false.
+ if(magoberr <= zero) magoberr=1.0_r_kind
+ error=one/(magoberr)
+ ratio_errors=one
+ if (jiter==1) then
+ if (oneobvalue > 0_r_kind) then
+ data(ifedob,i) = oneobvalue
+ ddiff = data(ifedob,i) - FEDMdiag(i)
+ else
+ ddiff = oneobddiff
+ data(ifedob,i) = FEDMdiag(i)+ddiff
+ oneobvalue = data(ifedob,i)
+ endif
+ write(6,*)"FED_ONEOB: O_Val,B_Val= ",data(ifedob,i),FEDMdiag(i)
+ write(6,*)"FED_ONEOB: Innov,Error= ",ddiff,magoberr
+ else
+ data(ifedob,i) = oneobvalue
+ ddiff = data(ifedob,i) - FEDMdiag(i)
+ end if
+ end if !oneob
+
+! Gross error checks
+ obserror = one/max(ratio_errors*error,tiny_r_kind)
+ obserrlm = max(cermin(ikx),min(cermax(ikx),obserror))
+ residual = abs(ddiff) != y-H(xb)
+ ratio = residual/obserrlm != y-H(xb)/sqrt(R)
+
+ if (l_set_oerr_ratio_fed) then
+ if (ratio > cgross(ikx) .or. ratio_errors < tiny_r_kind) then
+ if (luse(i)) awork(4) = awork(4)+one
+ error = zero
+ ratio_errors = zero
+ end if
+ else
+ ratio_errors = one
+ end if
+
+ if (ratio_errors*error <=tiny_r_kind) muse(i)=.false.
+! if (nobskeep>0 .and. luse_obsdiag) muse(i)=obsdiags(i_fed_ob_type,ibin)%tail%muse(nobskeep)
+ if (nobskeep>0.and.luse_obsdiag) call obsdiagNode_get(my_diag, jiter=nobskeep, muse=muse(i))
+
+ val = error*ddiff !=y-H(xb)/sqrt(R)
+
+! Compute penalty terms (linear & nonlinear qc).
+ if(luse(i))then
+ exp_arg = -half*val**2
+ rat_err2 = ratio_errors**2
+ val2=val*val !(o-g)**2/R, would be saved in awork
+ if (cvar_pg(ikx) > tiny_r_kind .and. error > tiny_r_kind) then
+ arg = exp(exp_arg)
+ wnotgross= one-cvar_pg(ikx)
+ cg_w=cvar_b(ikx)
+ wgross = cg_term*cvar_pg(ikx)/(cg_w*wnotgross)
+ term = log((arg+wgross)/(one+wgross))
+ wgt = one-wgross/(arg+wgross)
+ rwgt = wgt/wgtlim
+ else
+ term = exp_arg
+ wgt = wgtlim
+ rwgt = wgt/wgtlim
+ end if
+ valqc = -two*rat_err2*term
+
+! print*,'Compute penalty terms'
+! Accumulate statistics for obs belonging to this task
+ if (muse(i)) then
+ if(rwgt < one) awork(21) = awork(21)+one
+ jsig = dpres
+ jsig=max(1,min(jsig,nsig))
+ awork(6*nsig+jsig+100)=awork(6*nsig+jsig+100)+val2*rat_err2
+ awork(5*nsig+jsig+100)=awork(5*nsig+jsig+100)+one
+ awork(3*nsig+jsig+100)=awork(3*nsig+jsig+100)+valqc
+ end if
+! Loop over pressure level groupings and obs to accumulate
+! statistics as a function of observation type.
+ ress = scale*ddiff
+ ressw = ress*ress
+ nn=1
+ if (.not. muse(i)) then
+ nn=2
+ if(ratio_errors*error >=tiny_r_kind)nn=3
+ end if
+ do k = 1,npres_print
+! if(presw >=ptop(k) .and. presw<=pbot(k))then
+ if(presq >=ptopq(k) .and. presq<=pbotq(k))then
+ bwork(k,ikx,1,nn) = bwork(k,ikx,1,nn)+one ! count
+ bwork(k,ikx,2,nn) = bwork(k,ikx,2,nn)+ddiff ! bias
+ bwork(k,ikx,3,nn) = bwork(k,ikx,3,nn)+ressw ! (o-g)**2
+ bwork(k,ikx,4,nn) = bwork(k,ikx,4,nn)+val2*rat_err2 ! penalty
+ bwork(k,ikx,5,nn) = bwork(k,ikx,5,nn)+valqc ! nonlin qc penalty
+
+ end if
+ end do
+ end if
+
+ if(luse_obsdiag)then
+ call obsdiagNode_set(my_diag, luse=luse(i), wgtjo=(error*ratio_errors)**2, &
+ jiter=jiter, muse=muse(i), nldepart=ddiff)
+ end if
+
+! If obs is "acceptable", load array with obs info for use
+! in inner loop minimization (int* and stp* routines)
+ if ( .not. last .and. muse(i)) then
+
+ allocate(my_head) ! YPW added
+ call fedNode_appendto(my_head,fedhead(ibin))
+
+ my_head%idv=is
+ my_head%iob=i
+ my_head%elat= data(ilate,i)
+ my_head%elon= data(ilone,i)
+
+ my_head%dlev= dpres
+ call get_ijk(mm1,dlat,dlon,dpres,my_head%ij,my_head%wij)
+ my_head%res = ddiff ! Observation - ges
+ my_head%err2 = error**2
+ my_head%raterr2 = ratio_errors**2
+ my_head%time = dtime
+ my_head%b = cvar_b(ikx)
+ my_head%pg = cvar_pg(ikx)
+ my_head%luse = luse(i)
+
+ if(oberror_tune) then
+ ! my_head%fedpertb=data(iptrb,i)/error/ratio_errors
+ my_head%kx=ikx
+ if(presq > ptabl(2))then
+ my_head%k1=1
+ else if( presq <= ptabl(33)) then
+ my_head%k1=33
+ else
+ k_loop: do k=2,32
+ if(presq > ptabl(k+1) .and. presq <= ptabl(k)) then
+ my_head%k1=k
+ exit k_loop
+ end if
+ end do k_loop
+ end if
+ end if
+!-------------------------------------------------
+
+ if(luse_obsdiag)then
+ call obsdiagNode_assert(my_diag,my_head%idv,my_head%iob,1,myname,'my_diag:my_head')
+ my_head%diags => my_diag
+ end if
+
+ my_head => null()
+ end if
+
+! Save select output for diagnostic file
+ if(.not.luse(i))write(6,*)' luse, mype',luse(i),mype
+ if(fed_diagsave .and. luse(i))then
+ ii=ii+1
+ rstation_id = data(id,i)
+ err_input = data(ier2,i)
+ err_adjst = data(ier,i)
+ if (ratio_errors*error>tiny_r_kind) then
+ err_final = one/(ratio_errors*error)
+ else
+ err_final = huge_single
+ end if
+ errinv_input = huge_single
+ errinv_adjst = huge_single
+ errinv_final = huge_single
+ if (err_input>tiny_r_kind) errinv_input = one/err_input
+ if (err_adjst>tiny_r_kind) errinv_adjst = one/err_adjst
+ if (err_final>tiny_r_kind) errinv_final = one/err_final
+
+ if(binary_diag) call contents_binary_diag_(my_diag)
+ if(netcdf_diag) call contents_netcdf_diag_(my_diag)
+
+ end if
+ end do
+
+! Release memory of local guess arrays
+ call final_vars_
+
+! Write information to diagnostic file
+ if(fed_diagsave .and. netcdf_diag) call nc_diag_write
+ if(fed_diagsave .and. binary_diag .and. ii>0)then
+
+ write(string,600) jiter
+600 format('fed_',i2.2)
+ diag_file=trim(dirname) // trim(string)
+ if(init_pass) then
+ open(66,file=trim(diag_file),form='unformatted',status='unknown',position='rewind')
+ else
+ inquire(file=trim(diag_file),exist=diagexist)
+ if (diagexist) then
+ open(66,file=trim(diag_file),form='unformatted',status='old',position='append')
+ else
+ open(66,file=trim(diag_file),form='unformatted',status='unknown',position='rewind')
+ end if
+ end if
+ if(init_pass .and. mype == 0) then
+ write(66) ianldate
+ write(6,*)'SETUPFED: write time record to file ',&
+ trim(diag_file), ' ',ianldate
+ end if
+
+! call dtime_show(myname,'diagsave:fed',i_fed_ob_type)
+ write(66)'fed',nchar,nreal,ii,mype,ioff0
+ write(66)cdiagbuf(1:ii),rdiagbuf(:,1:ii)
+ ! write(6,*)'fed,nchar,nreal,ii,mype',nchar,nreal,ii,mype
+ deallocate(cdiagbuf,rdiagbuf)
+ close(66)
+ end if
+
+! End of routine
+
+
+! return
+
+ contains
+
+ subroutine check_vars_ (proceed)
+
+
+ logical,intent(inout) :: proceed
+ integer(i_kind) ivar, istatus
+! Check to see if required guess fields are available
+ call gsi_metguess_get ('var::ps', ivar, istatus )
+ proceed=ivar>0
+ call gsi_metguess_get ('var::z' , ivar, istatus )
+ proceed=proceed.and.ivar>0
+ call gsi_metguess_get ('var::q' , ivar, istatus )
+ proceed=proceed.and.ivar>0
+! call gsi_metguess_get ('var::tv' , ivar, istatus )
+! proceed=proceed.and.ivar>0
+ call gsi_metguess_get ('var::qs', ivar, istatus )
+ proceed=proceed.and.ivar>0
+ call gsi_metguess_get ('var::qg', ivar, istatus )
+ proceed=proceed.and.ivar>0
+ call gsi_metguess_get ('var::qr', ivar, istatus )
+ proceed=proceed.and.ivar>0
+ end subroutine check_vars_
+
+
+ subroutine init_vars_
+
+! use radaremul_cst, only: mphyopt
+ use obsmod, only: if_model_fed
+ real(r_kind),dimension(:,: ),pointer:: rank2=>NULL()
+ real(r_kind),dimension(:,:,:),pointer:: rank3=>NULL()
+ character(len=5) :: varname
+ integer(i_kind) ifld, istatus
+
+! If require guess vars available, extract from bundle ...
+ if(size(gsi_metguess_bundle)==nfldsig) then
+! get ps ...
+ varname='ps'
+ call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank2,istatus)
+ if (istatus==0) then
+ if(allocated(ges_ps))then
+ write(6,*) trim(myname), ': ', trim(varname), ' already incorrectly alloc '
+ call stop2(999)
+ end if
+ allocate(ges_ps(size(rank2,1),size(rank2,2),nfldsig))
+ ges_ps(:,:,1)=rank2
+ do ifld=2,nfldsig
+ call gsi_bundlegetpointer(gsi_metguess_bundle(ifld),trim(varname),rank2,istatus)
+ ges_ps(:,:,ifld)=rank2
+ end do
+ else
+ write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
+ call stop2(999)
+ end if
+! get z ...
+ varname='z'
+ call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank2,istatus)
+ if (istatus==0) then
+ if(allocated(ges_z))then
+ write(6,*) trim(myname), ': ', trim(varname), ' already incorrectly alloc '
+ call stop2(999)
+ end if
+ allocate(ges_z(size(rank2,1),size(rank2,2),nfldsig))
+ ges_z(:,:,1)=rank2
+ do ifld=2,nfldsig
+ call gsi_bundlegetpointer(gsi_metguess_bundle(ifld),trim(varname),rank2,istatus)
+ ges_z(:,:,ifld)=rank2
+ end do
+
+ if(if_model_fed)then
+ ! get fed ....
+ varname='fed'
+ call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank3,istatus)
+ if (istatus==0) then
+ if(allocated(ges_fed))then
+ write(6,*) trim(myname), ': ', trim(varname), ' already incorrectly alloc '
+ call stop2(999)
+ endif
+ allocate(ges_fed(size(rank3,1),size(rank3,2),size(rank3,3),nfldsig))
+ ges_fed(:,:,:,1)=rank3
+ do ifld=2,nfldsig
+ call gsi_bundlegetpointer(gsi_metguess_bundle(ifld),trim(varname),rank3,istatus)
+ ges_fed(:,:,:,ifld)=rank3
+ enddo
+ else
+ write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
+ call stop2(999)
+ endif
+ endif
+
+ else
+ write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
+ call stop2(999)
+ end if
+! get q ...
+ varname='q'
+ call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank3,istatus)
+ if (istatus==0) then
+ if(allocated(ges_q))then
+ write(6,*) trim(myname), ': ', trim(varname), ' already incorrectly alloc '
+ call stop2(999)
+ end if
+ allocate(ges_q(size(rank3,1),size(rank3,2),size(rank3,3),nfldsig))
+ ges_q(:,:,:,1)=rank3
+ do ifld=2,nfldsig
+ call gsi_bundlegetpointer(gsi_metguess_bundle(ifld),trim(varname),rank3,istatus)
+ ges_q(:,:,:,ifld)=rank3
+ end do
+ else
+ write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
+ call stop2(999)
+ end if
+! get tv ...
+! varname='tv'
+! call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank3,istatus)
+! if (istatus==0) then
+! if(allocated(ges_tv))then
+! write(6,*) trim(myname), ': ', trim(varname), ' already incorrectly alloc '
+! call stop2(999)
+! end if
+! allocate(ges_tv(size(rank3,1),size(rank3,2),size(rank3,3),nfldsig))
+! ges_tv(:,:,:,1)=rank3
+! do ifld=2,nfldsig
+! call gsi_bundlegetpointer(gsi_metguess_bundle(ifld),trim(varname),rank3,istatus)
+! ges_tv(:,:,:,ifld)=rank3
+! ges_tv(:,:,:,ifld)=rank3
+! end do
+! else
+! write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
+! call stop2(999)
+! end if
+! get qr ...
+! get qg ...
+ varname='qg'
+ call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank3,istatus)
+ if (istatus==0) then
+ if(allocated(ges_qg))then
+ write(6,*) trim(myname), ': ', trim(varname), ' already incorrectly alloc '
+ call stop2(999)
+ end if
+ allocate(ges_qg(size(rank3,1),size(rank3,2),size(rank3,3),nfldsig))
+ if(.not. allocated(ges_qg_mask))then
+ allocate(ges_qg_mask(size(rank3,1),size(rank3,2),size(rank3,3),nfldsig))
+ end if
+
+ ges_qg(:,:,:,1)=rank3
+ do ifld=2,nfldsig
+ call gsi_bundlegetpointer(gsi_metguess_bundle(ifld),trim(varname),rank3,istatus)
+ ges_qg(:,:,:,ifld)=rank3
+ end do
+ else
+ write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
+ call stop2(999)
+ end if
+ else
+ write(6,*) trim(myname), ': inconsistent vector sizes (nfldsig,size(metguess_bundle) ',&
+ nfldsig,size(gsi_metguess_bundle)
+ call stop2(999)
+ end if
+ end subroutine init_vars_
+
+ subroutine init_netcdf_diag_
+ character(len=80) string
+ character(len=128) diag_conv_file
+ integer(i_kind) ncd_fileid,ncd_nobs
+ logical append_diag
+ logical,parameter::verbose=.false.
+ write(string,900) jiter
+900 format('conv_fed_',i2.2,'.nc4')
+ diag_conv_file=trim(dirname) // trim(string)
+
+ inquire(file=diag_conv_file, exist=append_diag)
+
+ if (append_diag) then
+ call nc_diag_read_init(diag_conv_file,ncd_fileid)
+ ncd_nobs = nc_diag_read_get_dim(ncd_fileid,'nobs')
+ call nc_diag_read_close(diag_conv_file)
+
+ if (ncd_nobs > 0) then
+ if(verbose) print *,'file ' // trim(diag_conv_file) // ' exists. Appending. nobs,mype=',ncd_nobs,mype
+ else
+ if(verbose) print *,'file ' // trim(diag_conv_file) // ' exists but contains no obs. Not appending. nobs,mype=',ncd_nobs,mype
+ append_diag = .false. ! if there are no obs in existing file, then do not try to append
+ end if
+ end if
+
+ call nc_diag_init(diag_conv_file, append=append_diag)
+
+ if (.not. append_diag) then ! don't write headers on append - the module will break?
+ call nc_diag_header("date_time",ianldate )
+ call nc_diag_header("Number_of_state_vars", nsdim )
+ end if
+ end subroutine init_netcdf_diag_
+ subroutine contents_binary_diag_(odiag)
+ type(obs_diag),pointer,intent(in):: odiag
+
+ cdiagbuf(ii) = station_id ! station id
+
+ rdiagbuf(1,ii) = ictype(ikx) ! observation type
+ rdiagbuf(2,ii) = icsubtype(ikx) ! observation subtype
+
+ rdiagbuf(3,ii) = data(ilate,i) ! observation latitude (degrees)
+ rdiagbuf(4,ii) = data(ilone,i) ! observation longitude (degrees)
+
+ rdiagbuf(5,ii) = data(istnelv,i) ! station elevation (meters)
+ rdiagbuf(6,ii) = presq ! observation pressure (hPa)
+ rdiagbuf(7,ii) = data(iobshgt,i) ! observation height (meters)
+ rdiagbuf(8,ii) = (dtime*r60)-time_offset ! obs time (sec relative to analysis time)
+ rdiagbuf(9,ii) = data(iqc,i) ! input prepbufr qc or event mark
+ rdiagbuf(10,ii) = rmiss_single ! setup qc or event mark
+ rdiagbuf(11,ii) = data(iuse,i) ! read_prepbufr data usage flag
+ if(muse(i)) then
+ rdiagbuf(12,ii) = one ! analysis usage flag (1=use, -1=not used)
+ else
+ rdiagbuf(12,ii) = -one
+ end if
+
+ rdiagbuf(13,ii) = rwgt ! nonlinear qc relative weight
+ rdiagbuf(14,ii) = errinv_input ! prepbufr inverse obs error (dBZ)**-1
+ rdiagbuf(15,ii) = errinv_adjst ! read_prepbufr inverse obs error (dBZ)**-1
+ rdiagbuf(16,ii) = errinv_final ! final inverse observation error (dBZ)**-1
+ rdiagbuf(17,ii) = data(ifedob,i) ! radar reflectivity observation (dBZ)
+ rdiagbuf(18,ii) = ddiff ! obs-ges (dBZ)
+ rdiagbuf(19,ii) = data(ifedob,i)-FEDMdiag(i) ! obs-ges w/o bias correction (dBZ) (future slot)
+ rdiagbuf(20,ii) = dlat8km ! j-index on 8km bufr obs grid
+ rdiagbuf(21,ii) = dlon8km ! i-index on 8km bufr obs grid
+
+! print*,'data(ilat,i)=',data(ilat,i),'data(ilon,i)=',data(ilon,i)
+
+ rdiagbuf(22,ii) = FEDMdiag(i) ! dBZ from rain water
+
+ rdiagbuf(23,ii) = T1D ! temperature (sensible, K)
+ rdiagbuf(24,ii) = RHO ! air density (kg/m**3)
+
+ if (lobsdiagsave) then
+ write(6,*)'wrong here, stop in setupfed.f90 '
+ stop
+ ioff=nreal
+ do jj=1,miter
+ ioff=ioff+1
+ if (odiag%muse(jj)) then
+ rdiagbuf(ioff,ii) = one
+ else
+ rdiagbuf(ioff,ii) = -one
+ end if
+ end do
+ do jj=1,miter+1
+ ioff=ioff+1
+ rdiagbuf(ioff,ii) = odiag%nldepart(jj)
+ end do
+ do jj=1,miter
+ ioff=ioff+1
+ rdiagbuf(ioff,ii) = odiag%tldepart(jj)
+ end do
+ do jj=1,miter
+ ioff=ioff+1
+ rdiagbuf(ioff,ii) = odiag%obssen(jj)
+ end do
+ end if
+
+ end subroutine contents_binary_diag_
+ subroutine contents_netcdf_diag_(odiag)
+ type(obs_diag),pointer,intent(in):: odiag
+! Observation class
+ character(7),parameter :: obsclass = ' fed'
+ real(r_kind),dimension(miter) :: obsdiag_iuse
+ call nc_diag_metadata("Station_ID", station_id )
+ call nc_diag_metadata("Observation_Class", obsclass )
+ call nc_diag_metadata("Observation_Type", ictype(ikx) )
+ call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
+ call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
+ call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
+ call nc_diag_metadata("Station_Elevation", sngl(data(istnelv,i)) )
+ call nc_diag_metadata("Pressure", sngl(presq) )
+ call nc_diag_metadata("Height", sngl(data(iobshgt,i)) )
+ call nc_diag_metadata("Time", sngl(dtime*r60-time_offset))
+ call nc_diag_metadata("Prep_QC_Mark", sngl(data(iqc,i)) )
+ call nc_diag_metadata("Prep_Use_Flag", sngl(data(iuse,i)) )
+! call nc_diag_metadata("Nonlinear_QC_Var_Jb", var_jb ! )
+ call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
+ if(muse(i)) then
+ call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
+ else
+ call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
+ end if
+
+ call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
+ call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
+ call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
+
+ call nc_diag_metadata("Observation", sngl(data(ifedob,i)) )
+ call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ddiff) )
+ call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(data(ifedob,i)-FEDMdiag(i)) )
+ if (lobsdiagsave) then
+ do jj=1,miter
+ if (odiag%muse(jj)) then
+ obsdiag_iuse(jj) = one
+ else
+ obsdiag_iuse(jj) = -one
+ end if
+ end do
+
+ call nc_diag_data2d("ObsDiagSave_iuse", obsdiag_iuse )
+ call nc_diag_data2d("ObsDiagSave_nldepart", odiag%nldepart )
+ call nc_diag_data2d("ObsDiagSave_tldepart", odiag%tldepart )
+ call nc_diag_data2d("ObsDiagSave_obssen" , odiag%obssen )
+ end if
+
+ end subroutine contents_netcdf_diag_
+
+ subroutine final_vars_
+ if(allocated(ges_z )) deallocate(ges_z )
+ if(allocated(ges_q )) deallocate(ges_q )
+! if(allocated(ges_tv)) deallocate(ges_tv)
+ if(allocated(ges_ps)) deallocate(ges_ps)
+ if(allocated(ges_qg)) deallocate(ges_qg)
+ if(allocated(ges_fed)) deallocate(ges_fed)
+ end subroutine final_vars_
+
+ subroutine init_qcld(t_cld, qxmin_cld, icat_cld, t_dpnd)
+ use kinds, only: r_kind,r_single,r_double,i_kind
+ implicit none
+ real(r_kind), intent(in ) :: t_cld
+ real(r_kind), intent(inout) :: qxmin_cld
+ integer, intent(in ) :: icat_cld
+ logical, intent(in ) :: t_dpnd
+!
+! local variables
+ real :: tr_ll, qrmin_ll, tr_hl, qrmin_hl
+ real :: ts_ll, qsmin_ll, ts_hl, qsmin_hl
+ real :: tg_ll, qgmin_ll, tg_hl, qgmin_hl
+ real :: qr_min, qs_min, qg_min
+!------------------------------------------------------
+
+ qr_min = 5.0E-6_r_kind
+ qs_min = 5.0E-6_r_kind
+ qg_min = 5.0E-6_r_kind
+ tr_ll = 275.65; qrmin_ll = 5.0E-6_r_kind;
+ tr_hl = 270.65; qrmin_hl = 1.0E-8_r_kind;
+ ts_ll = 275.65; qsmin_ll = 1.0E-8_r_kind;
+ ts_hl = 270.65; qsmin_hl = 5.0E-6_r_kind;
+ tg_ll = 275.65; qgmin_ll = 1.0E-6_r_kind;
+ tg_hl = 270.65; qgmin_hl = 5.0E-6_r_kind;
+
+ select case (icat_cld)
+ case (1)
+ if ( t_dpnd ) then
+ if (t_cld <= tr_hl) then
+ qxmin_cld = qrmin_hl
+ else if (t_cld >= tr_ll) then
+ qxmin_cld = qrmin_ll
+ else
+ qxmin_cld = (qrmin_hl + qrmin_ll) * 0.5
+ end if
+ else
+ qxmin_cld = qr_min
+ end if
+ case default
+ write(6,*) 'wrong cloud hydrometer category ID',icat_cld
+ end select
+
+ return
+
+ end subroutine init_qcld
+
+end subroutine setupfed
+end module fed_setup
diff --git a/src/gsi/setupgust.f90 b/src/gsi/setupgust.f90
index 65f4c3caba..c6b4aa260f 100644
--- a/src/gsi/setupgust.f90
+++ b/src/gsi/setupgust.f90
@@ -224,7 +224,7 @@ subroutine setupgust(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diag
goverrd=grav/rd
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! Check for missing data
diff --git a/src/gsi/setuphowv.f90 b/src/gsi/setuphowv.f90
index c2b1dfe3e9..3ecb05c8ff 100644
--- a/src/gsi/setuphowv.f90
+++ b/src/gsi/setuphowv.f90
@@ -195,7 +195,7 @@ subroutine setuphowv(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diag
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
hr_offset=min_offset/60.0_r_kind
diff --git a/src/gsi/setuplag.f90 b/src/gsi/setuplag.f90
index 0bad754a0c..01692d8164 100644
--- a/src/gsi/setuplag.f90
+++ b/src/gsi/setuplag.f90
@@ -171,7 +171,7 @@ subroutine setuplag(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diags
allocate(cdiagbuf(nobs),rdiagbuf(nreal,nobs))
end if
scale=one
- rsig=float(nsig)
+ rsig=real(nsig,r_kind)
mm1=mype+1
call dtime_setup()
diff --git a/src/gsi/setuplcbas.f90 b/src/gsi/setuplcbas.f90
index 962abbecaa..508236ec26 100644
--- a/src/gsi/setuplcbas.f90
+++ b/src/gsi/setuplcbas.f90
@@ -191,7 +191,7 @@ subroutine setuplcbas(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_dia
scale=one
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! Check for missing data
diff --git a/src/gsi/setuplight.f90 b/src/gsi/setuplight.f90
index e9ed19d3c3..505008b4e9 100644
--- a/src/gsi/setuplight.f90
+++ b/src/gsi/setuplight.f90
@@ -90,7 +90,7 @@ subroutine setuplight(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,light_di
nobskeep,lobsdiag_allocated
use obsmod, only: netcdf_diag, binary_diag, dirname, ianldate
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim, nc_diag_read_close
use obsmod, only: luse_obsdiag
use m_obsNode, only: obsNode
@@ -421,7 +421,7 @@ subroutine setuplight(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,light_di
nobs_loc=zero
do i=1,nobs
- muse(i)=nint(data(11,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
enddo
dup=one
@@ -534,7 +534,7 @@ subroutine setuplight(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,light_di
! eps0 - guess value of lightning flash rate
if(nobs_gbl > 0) then
- eps=eps0*exp( (one/ float(nobs_gbl))*sum_gbl/(one+r0/w0) )
+ eps=eps0*exp( (one/ real(nobs_gbl,r_kind))*sum_gbl/(one+r0/w0) )
else
eps=eps0
endif !! if(nobs_gbl .gt. 0) then
@@ -1619,25 +1619,25 @@ subroutine contents_netcdf_diag_(odiag)
real(r_single),parameter:: missing = -9.99e9_r_single
real(r_kind),dimension(miter) :: obsdiag_iuse
- call nc_diag_metadata("GLM_Detect_Err", sngl(data(ier,i)) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
- call nc_diag_metadata("Lightning_FR_Obs", sngl(dlight ) )
- call nc_diag_metadata("Time", sngl(dtime) )
- call nc_diag_metadata("GLM_QC_Mark", sngl(data(iqc,i)) )
- call nc_diag_metadata("GLM_Orig_Detect_Err", sngl(data(ier2,i)) )
- call nc_diag_metadata("GLM_Use_Flag", sngl(data(iuse,i)) )
+ call nc_diag_metadata_to_single("GLM_Detect_Err", data(ier,i) )
+ call nc_diag_metadata_to_single("Latitude", data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude", data(ilone,i) )
+ call nc_diag_metadata_to_single("Lightning_FR_Obs", dlight )
+ call nc_diag_metadata_to_single("Time", dtime )
+ call nc_diag_metadata_to_single("GLM_QC_Mark", data(iqc,i) )
+ call nc_diag_metadata_to_single("GLM_Orig_Detect_Err", data(ier2,i) )
+ call nc_diag_metadata_to_single("GLM_Use_Flag", data(iuse,i) )
if(muse(i)) then
call nc_diag_metadata("Analysis_Use_Flag", 1._r_single )
else
call nc_diag_metadata("Analysis_Use_Flag", -1._r_single )
endif
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
- call nc_diag_metadata("Obs_Minus_Forecast_VarBC", sngl(ddiff) )
- call nc_diag_metadata("Obs_Minus_Forecast_NoVarBC", sngl(dlight-lightges0) )
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",rwgt )
+ call nc_diag_metadata_to_single("Errinv_Input", errinv_input )
+ call nc_diag_metadata_to_single("Errinv_Adjust", errinv_adjst )
+ call nc_diag_metadata_to_single("Errinv_Final", errinv_final )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_VarBC",ddiff )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_NoVarBC",dlight,lightges0,'-')
if (lobsdiagsave) then
do jj=1,miter
if (odiag%muse(jj)) then
@@ -1650,7 +1650,7 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_data2d("ObsDiagSave_iuse", obsdiag_iuse )
call nc_diag_data2d("ObsDiagSave_nldepart", odiag%nldepart )
call nc_diag_data2d("ObsDiagSave_tldepart", odiag%tldepart )
- call nc_diag_data2d("ObsDiagSave_obssen", odiag%obssen )
+ call nc_diag_data2d("ObsDiagSave_obssen", odiag%obssen )
endif
end subroutine contents_netcdf_diag_
diff --git a/src/gsi/setuplwcp.f90 b/src/gsi/setuplwcp.f90
index 7e06144f68..d020cbbc90 100644
--- a/src/gsi/setuplwcp.f90
+++ b/src/gsi/setuplwcp.f90
@@ -68,7 +68,7 @@ subroutine setuplwcp(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diag
use obsmod, only: netcdf_diag, binary_diag, dirname
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header,nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim,nc_diag_read_close
use state_vectors, only: svars3d, levels
@@ -274,7 +274,7 @@ subroutine setuplwcp(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diag
iobshgt=16 ! index of observation height (m)
do i=1,nobs
- muse(i)=nint(data(11,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
dup=one
@@ -848,28 +848,28 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_metadata("Observation_Class", obsclass )
call nc_diag_metadata("Observation_Type", ictype(ikx) )
call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
- call nc_diag_metadata("Station_Elevation", sngl(data(istnelv,i)) )
- call nc_diag_metadata("Pressure", sngl(data(iobsprs,i)) )
- call nc_diag_metadata("Height", sngl(data(iobshgt,i)) )
- call nc_diag_metadata("Time", sngl(dtime-time_offset))
- call nc_diag_metadata("Prep_QC_Mark", sngl(data(iqc,i)) )
- call nc_diag_metadata("Setup_QC_Mark", sngl(rmiss_single) )
- call nc_diag_metadata("Prep_Use_Flag", sngl(data(iuse,i)) )
+ call nc_diag_metadata_to_single("Latitude", data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude", data(ilone,i) )
+ call nc_diag_metadata_to_single("Station_Elevation",data(istnelv,i) )
+ call nc_diag_metadata_to_single("Pressure", data(iobsprs,i) )
+ call nc_diag_metadata_to_single("Height", data(iobshgt,i) )
+ call nc_diag_metadata_to_single("Time", dtime,time_offset,'-' )
+ call nc_diag_metadata_to_single("Prep_QC_Mark", data(iqc,i) )
+ call nc_diag_metadata("Setup_QC_Mark", rmiss_single )
+ call nc_diag_metadata_to_single("Prep_Use_Flag", data(iuse,i) )
if(muse(i)) then
- call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
+ call nc_diag_metadata("Analysis_Use_Flag", 1.0_r_single )
else
- call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
+ call nc_diag_metadata("Analysis_Use_Flag", -1.0_r_single )
endif
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
- call nc_diag_metadata("Observation", sngl(dlwcp) )
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ddiff) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(dlwcp-lwcpges))
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",rwgt )
+ call nc_diag_metadata_to_single("Errinv_Input", errinv_input )
+ call nc_diag_metadata_to_single("Errinv_Adjust", errinv_adjst )
+ call nc_diag_metadata_to_single("Errinv_Final", errinv_final )
+ call nc_diag_metadata_to_single("Observation", dlwcp )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",ddiff )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted",dlwcp,lwcpges,'-')
if (lobsdiagsave) then
do jj=1,miter
diff --git a/src/gsi/setupmitm.f90 b/src/gsi/setupmitm.f90
index 89b01acbec..cc5b16fde3 100644
--- a/src/gsi/setupmitm.f90
+++ b/src/gsi/setupmitm.f90
@@ -195,7 +195,7 @@ subroutine setupmitm(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diag
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! Check for duplicate observations at same location
diff --git a/src/gsi/setupmxtm.f90 b/src/gsi/setupmxtm.f90
index 0c71415f80..5f332c4de5 100644
--- a/src/gsi/setupmxtm.f90
+++ b/src/gsi/setupmxtm.f90
@@ -195,7 +195,7 @@ subroutine setupmxtm(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diag
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! Check for duplicate observations at same location
diff --git a/src/gsi/setupoz.f90 b/src/gsi/setupoz.f90
index 24381df447..9e52bf4bf2 100644
--- a/src/gsi/setupoz.f90
+++ b/src/gsi/setupoz.f90
@@ -83,6 +83,9 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
! 2017-02-09 guo - Remove m_alloc, n_alloc.
! . Remove my_node with corrected typecast().
! 2017-10-27 todling - revised netcdf output for lay case; obs-sens needs attention
+! 2020-02-26 todling - reset obsbin from hr to min
+! 2022-08-10 karpowicz - fixes to ncdiag air_pressure_levels, change mass output to
+! ppmv/mole fraction, fix ompsnm scan positoin and solar zenith angle.
!
! input argument list:
! lunin - unit from which to read observations
@@ -110,10 +113,10 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
use mpeu_util, only: die,perr,getindex
use kinds, only: r_kind,r_single,i_kind
- use state_vectors, only: svars3d, levels
+ use state_vectors, only: svars3d, levels, nsdim
- use constants, only : zero,half,one,two,tiny_r_kind
- use constants, only : rozcon,cg_term,wgtlim,h300,r10
+ use constants, only : zero,half,one,two,tiny_r_kind,s_missing
+ use constants, only : constoz,rozcon,cg_term,wgtlim,h300,r10,r100,r1000
use m_obsdiagNode, only : obs_diag
use m_obsdiagNode, only : obs_diags
@@ -131,10 +134,11 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
use m_obsLList, only : obsLList
use obsmod, only : nloz_omi
use obsmod, only : luse_obsdiag
+! use obsmod, only : wrtgeovals
use obsmod, only: netcdf_diag, binary_diag, dirname
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim, nc_diag_read_close
use gsi_4dvar, only: nobs_bins,hr_obsbin
@@ -155,8 +159,8 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
implicit none
! !INPUT PARAMETERS:
- type(obsLList ),target,dimension(:),intent(in):: obsLL
- type(obs_diags),target,dimension(:),intent(in):: odiagLL
+ type(obsLList ),target,dimension(:),intent(inout):: obsLL
+ type(obs_diags),target,dimension(:),intent(inout):: odiagLL
integer(i_kind) , intent(in ) :: lunin ! unit from which to read observations
integer(i_kind) , intent(in ) :: mype ! mpi task id
@@ -191,9 +195,9 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
! Declare local variables
- real(r_kind) omg,rat_err2,dlat,dtime,dlon,rat_err4diag
+ real(r_kind) omg,rat_err2,dlat,dtime,dlon
real(r_kind) cg_oz,wgross,wnotgross,wgt,arg,exp_arg,term
- real(r_kind) psi,errorinv
+ real(r_kind) psi,errorinv,rat_err4diag
real(r_kind),dimension(nlevs):: ozges,varinv3,ozone_inv,ozobs,varinv4diag
real(r_kind),dimension(nlevs):: ratio_errors,error
real(r_kind),dimension(nlevs-1):: ozp
@@ -201,6 +205,7 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
real(r_kind),dimension(nlevs):: pobs,gross,tnoise
real(r_kind),dimension(nreal+nlevs,nobs):: data
real(r_kind),dimension(nsig+1)::prsitmp
+ real(r_kind),dimension(nsig)::ozgestmp ! GeoVaLs for JEDI/UFO
real(r_single),dimension(nlevs):: pob4,grs4,err4
real(r_single),dimension(ireal,nobs):: diagbuf
real(r_single),allocatable,dimension(:,:,:)::rdiagbuf
@@ -214,10 +219,10 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
type(sparr2) :: dhx_dx
integer(i_kind) i,nlev,ii,jj,iextra,ibin, kk, nperobs
- integer(i_kind) k,j,nz,jc,idia,irdim1,istatus,ioff0
+ integer(i_kind) k1,k2,k,j,nz,jc,idia,irdim1,istatus,ioff0,ioff1
integer(i_kind) ioff,itoss,ikeep,ierror_toq,ierror_poq
integer(i_kind) isolz,ifovn,itoqf
- integer(i_kind) mm1,itime,ilat,ilon,ilate,ilone,itoq,ipoq
+ integer(i_kind) mm1,itime,ilat,ilon,ilate,ilone,itoq,ipoq,iafbo !emily
integer(i_kind),dimension(iint,nobs):: idiagbuf
integer(i_kind),dimension(nlevs):: ipos,iouse,ikeepk
@@ -252,6 +257,9 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
call init_vars_
mm1=mype+1
+
+ write(6,*)'emily checking: you are here ...', myname, obstype
+
!
!*********************************************************************************
! Initialize arrays
@@ -280,7 +288,7 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
iouse(jc)=iuse_oz(j)
tnoise(jc)=error_oz(j)
gross(jc)=min(r10*gross_oz(j),h300)
- if (obstype == 'sbuv2' .or. obstype == 'ompsnp') then
+ if (obstype == 'sbuv2' .or. obstype == 'ompsnp' .or. obstype == 'ompsnpnc') then
pobs(jc)=pob_oz(j) * 1.01325_r_kind
else
pobs(jc)=pob_oz(j)
@@ -319,6 +327,7 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
irdim1=7
ioff0=irdim1
if(lobsdiagsave) irdim1=irdim1+4*miter+1
+ ioff1=irdim1
if (save_jacobian) then
nnz = nsig ! number of non-zero elements in dH(x)/dx profile
nind = 1
@@ -345,7 +354,7 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
isolz=8 ! index of solar zenith angle (gome and omi only)
itoqf=9 ! index of row anomaly (omi only)
ifovn=14 ! index of scan position (gome and omi only)
-
+ iafbo=15 ! index of algorithm flag for best ozone (for omi, ompsnm, and ompstc8) !emily
! If requested, save data for diagnostic ouput
if(ozone_diagsave)ii=0
@@ -363,7 +372,7 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
dlon=data(ilon,i)
dtime=data(itime,i)
- if (obstype == 'sbuv2' .or. obstype == 'ompsnp') then
+ if (obstype == 'sbuv2' .or. obstype == 'ompsnp' .or. obstype == 'ompsnpnc') then
if (nobskeep>0) then
! write(6,*)'setupozlay: nobskeep',nobskeep
call stop2(259)
@@ -388,7 +397,7 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
enddo
end if
- if (obstype == 'omieff' .or. obstype == 'tomseff') then
+ if (obstype == 'omieff' .or. obstype == 'tomseff' .or. obstype == 'ompsnmeff') then
pob_oz_omi(nloz_omi) = 1000.0_r_kind* 1.01325_r_kind
do j=nloz_omi-1, 1, -1
pob_oz_omi(j) = pob_oz_omi(j+1)/2.0
@@ -409,8 +418,18 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
ozp_omi(nloz_omi) = prsitmp(1)
call grdcrd1(ozp_omi(nloz_omi),prsitmp,nsig+1,-1)
end if
-
- if (obstype /= 'omieff' .and. obstype /= 'tomseff') then
+
+ ! GeoVaLs for JEDI/UFO
+ call tintrp2a1(ges_oz,ozgestmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+
+ ! need call to get pressures for pressure level output in ncdiags
+ call tintrp2a1(ges_prsi,prsitmp,dlat,dlon,dtime,hrdifsig,&
+ nsig+1,mype,nfldsig)
+
+
+ if (obstype /= 'omieff' .and. obstype /= 'tomseff' .and. &
+ obstype /= 'ompsnmeff' ) then
call intrp3oz1(ges_oz,ozges,dlat,dlon,ozp,dtime,&
nlevs,mype,doz_dz)
endif
@@ -441,7 +460,7 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
! For OMI/GOME, nlev=1
do k=1,nlev
j=ipos(k)
- if (obstype == 'omieff' .or. obstype == 'tomseff' ) then
+ if (obstype == 'omieff' .or. obstype == 'tomseff' .or. obstype == 'ompsnmeff') then
ioff=ifovn+1 !
else
ioff=nreal+k ! SBUV and OMI w/o efficiency factors
@@ -449,7 +468,7 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
! Compute innovation and load obs error into local array
! KW OMI and TOMS have averaging kernels
- if (obstype == 'omieff' .or. obstype == 'tomseff' ) then
+ if (obstype == 'omieff' .or. obstype == 'tomseff' .or. obstype == 'ompsnmeff') then
! everything in data is from top to bottom
nlayers = nloz_omi + 1
apriori(1:nloz_omi) = data(ioff:ioff+nloz_omi -1, i)
@@ -542,7 +561,8 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
rdiagbuf(3,k,ii) = errorinv ! inverse observation error
if (obstype == 'gome' .or. obstype == 'omieff' .or. &
obstype == 'omi' .or. obstype == 'tomseff' .or. &
- obstype == 'ompstc8') then
+ obstype == 'ompsnmeff' .or. obstype == 'ompstc8' .or. &
+ obstype == 'ompsnm') then
rdiagbuf(4,k,ii) = data(isolz,i) ! solar zenith angle
rdiagbuf(5,k,ii) = data(ifovn,i) ! field of view number
else
@@ -556,7 +576,7 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
endif
rdiagbuf(7,k,ii) = 1.e+10_r_single ! spread (filled in by EnKF)
- idia = ioff0
+ idia = ioff1
if (save_jacobian) then
oz_ind = getindex(svars3d, 'oz')
if (oz_ind < 0) then
@@ -574,34 +594,76 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
endif
if (netcdf_diag) then
+ k1 = k
+ k2 = k - 1
+ if(k2 == 0)k2 = 1
+ if(k == nlevs)then
+ k1=nlevs-1
+ k2=1
+ endif
+ if (obstype == 'sbuv2' .or. obstype == 'ompsnp' .or. obstype == 'ompsnpnc' ) then
+ call nc_diag_metadata_to_single("TopLevelPressure",pobs(k2)*r100)
+ call nc_diag_metadata_to_single("BottomLevelPressure", &
+ (pobs(k1)*r100))
+ else
+ call &
+ nc_diag_metadata_to_single("TopLevelPressure",prsitmp(nsig+1)*r1000)
+ call nc_diag_metadata_to_single("BottomLevelPressure", &
+ prsitmp(1)*r1000)
+ endif
+ call nc_diag_metadata("MPI_Task_Number", mype )
+ call nc_diag_metadata_to_single("Latitude",(data(ilate,i)) )
+ call nc_diag_metadata_to_single("Longitude",(data(ilone,i)) )
+ if(isnan(dtime) .or. isnan(time_offset)) then
+ call nc_diag_metadata("Time",s_missing)
+ else
+ call nc_diag_metadata_to_single("Time",dtime-time_offset)
+ endif
+ call nc_diag_data2d("mole_fraction_of_ozone_in_air", sngl(ozgestmp*constoz))
+ call nc_diag_data2d("air_pressure_levels",sngl(prsitmp*r1000))
call nc_diag_metadata("MPI_Task_Number", mype )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
- call nc_diag_metadata("Time", sngl(data(itime,i)-time_offset) )
- call nc_diag_metadata("Reference_Pressure", sngl(pobs(k)) )
- call nc_diag_metadata("Analysis_Use_Flag", iouse(k) )
- call nc_diag_metadata("Observation", sngl(ozobs(k)))
- call nc_diag_metadata("Inverse_Observation_Error", sngl(errorinv))
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ozone_inv(k)))
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted",sngl(ozone_inv(k)))
+ call nc_diag_metadata_to_single("Latitude", data(ilate,i))
+ call nc_diag_metadata_to_single("Longitude", data(ilone,i))
+ call nc_diag_metadata_to_single("Time", data(itime,i)-time_offset)
+ call nc_diag_metadata("Total_Ozone_Error_Flag", float(ierror_toq) )
+ call nc_diag_metadata("Profile_Ozone_Error_Flag", float(ierror_poq) )
+ call nc_diag_metadata_to_single("Reference_Pressure",(pobs(k)*r100))
+ call nc_diag_metadata("Analysis_Use_Flag", float(iouse(k)) )
+ call nc_diag_metadata_to_single("Observation",(ozobs(k)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error",(errorinv))
+ call nc_diag_metadata_to_single("Input_Observation_Error", (error(k)))
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",(ozone_inv(k)))
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted",(ozone_inv(k)))
+ call nc_diag_metadata_to_single("Forecast_unadjusted", (ozges(k)))
+ call nc_diag_metadata_to_single("Forecast_adjusted", (ozges(k)))
if (obstype == 'gome' .or. obstype == 'omieff' .or. &
- obstype == 'omi' .or. obstype == 'tomseff' ) then
- call nc_diag_metadata("Solar_Zenith_Angle", sngl(data(isolz,i)) )
- call nc_diag_metadata("Scan_Position", sngl(data(ifovn,i)) )
+ obstype == 'omi' .or. obstype == 'tomseff' .or. &
+ obstype == 'ompsnmeff' .or. obstype == 'ompsnm') then
+ call nc_diag_metadata_to_single("Solar_Zenith_Angle",(data(isolz,i)) )
+ call nc_diag_metadata_to_single("Scan_Position",(data(ifovn,i)) )
else
- call nc_diag_metadata("Solar_Zenith_Angle", sngl(rmiss) )
- call nc_diag_metadata("Scan_Position", sngl(rmiss) )
+ call nc_diag_metadata_to_single("Solar_Zenith_Angle",(rmiss) )
+ call nc_diag_metadata_to_single("Scan_Position",(rmiss) )
endif
if (obstype == 'omieff' .or. obstype == 'omi' ) then
- call nc_diag_metadata("Row_Anomaly_Index", sngl(data(itoqf,i)) )
+ call nc_diag_metadata_to_single("Row_Anomaly_Index",(data(itoqf,i)) )
else
- call nc_diag_metadata("Row_Anomaly_Index", sngl(rmiss) )
+ call nc_diag_metadata_to_single("Row_Anomaly_Index",(rmiss) )
endif
+!>>emily
+ if (obstype == 'omi' .or. obstype == 'ompstc8' .or. obstype == 'ompsnm') then
+ call nc_diag_metadata_to_single("Algorithm_Flag_For_Best_Ozone", data(iafbo,i))
+ endif
+!< my_diag)
- idia=6
+ idia=ioff0
do jj=1,miter
idia=idia+1
if (odiag%muse(jj)) then
@@ -785,7 +849,7 @@ subroutine setupozlay(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
if(in_curbin) then
if (ozone_diagsave.and.lobsdiagsave.and.luse(i)) then
- rdiagbuf(7:irdim1,1:nlevs,ii) = zero
+ rdiagbuf(ioff0+1:irdim1,1:nlevs,ii) = zero
endif
endif ! (in_curbin)
@@ -932,6 +996,7 @@ subroutine init_netcdf_diag_
call nc_diag_header("Satellite_Sensor", isis)
call nc_diag_header("Satellite", dplat(is))
call nc_diag_header("Observation_type", obstype)
+ call nc_diag_header("Number_of_state_vars", nsdim )
call nc_diag_header("pobs", pobs)
call nc_diag_header("gross",gross)
call nc_diag_header("tnoise",tnoise)
@@ -995,7 +1060,9 @@ subroutine setupozlev(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
! 2016-12-09 mccarty - add netcdf_diag capability
! 2017-02-09 guo - Remove m_alloc, n_alloc.
! . Remove my_node with corrected typecast().
-!
+! 2020-02-26 todling - reset obsbin from hr to min
+! 2022-08-10 karpowicz/todling - replace ncdiag analysis use flag with +/-1 instead of zero
+!
! input argument list:
! lunin - unit from which to read observations
! mype - mpi task id
@@ -1036,8 +1103,9 @@ subroutine setupozlev(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
use obsmod, only : mype_diaghdr,dirname,time_offset,ianldate
use obsmod, only : lobsdiag_allocated,lobsdiagsave,lobsdiag_forenkf
use obsmod, only: netcdf_diag, binary_diag, dirname
+! use obsmod, only: wrtgeovals
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim, nc_diag_read_close
use m_obsNode, only: obsNode
use m_o3lNode, only : o3lNode
@@ -1046,9 +1114,10 @@ subroutine setupozlev(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
use obsmod, only : luse_obsdiag
use guess_grids, only : nfldsig,ges_lnprsl,hrdifsig
+ use guess_grids, only : ges_prsi,ntguessig
use constants, only : zero,half,one,two,tiny_r_kind,four
- use constants, only : cg_term,wgtlim,r10,constoz
+ use constants, only : cg_term,wgtlim,r10,r100,r1000,constoz
use gsi_4dvar, only: nobs_bins,hr_obsbin
@@ -1066,8 +1135,8 @@ subroutine setupozlev(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
implicit none
! !INPUT PARAMETERS:
- type(obsLList ),target,dimension(:),intent(in):: obsLL
- type(obs_diags),target,dimension(:),intent(in):: odiagLL
+ type(obsLList ),target,dimension(:),intent(inout):: obsLL
+ type(obs_diags),target,dimension(:),intent(inout):: odiagLL
integer(i_kind) , intent(in ) :: lunin ! unit from which to read observations
integer(i_kind) , intent(in ) :: mype ! mpi task id
@@ -1106,26 +1175,30 @@ subroutine setupozlev(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
real(r_kind) o3ges, o3ppmv
real(r_kind) rlow,rhgh,sfcchk
- real(r_kind) omg,rat_err2,dlat,dtime,dlon,rat_err4diag
+ real(r_kind) omg,rat_err2,dlat,dtime,dlon
real(r_kind) cg_oz,wgross,wnotgross,wgt,arg,exp_arg,term
real(r_kind) errorinv
- real(r_kind) psges,ozlv,airnd,uvnd,visnd
+ real(r_kind) psges,ozlv, airnd, uvnd, visnd
- real(r_kind) varinv3,ratio_errors,varinv4diag
+ real(r_kind) varinv3,ratio_errors
+ real(r_kind) varinv4diag,rat_err4diag
real(r_kind) dpres,obserror,ozone_inv,preso3l
real(r_kind),dimension(nreal+nlevs,nobs):: data
real(r_kind),dimension(nsig):: prsltmp
+ real(r_kind),dimension(nsig+1)::prsitmp
+ real(r_kind),dimension(nsig)::ozgestmp ! GeoVaLs for JEDI/UFO
real(r_single),dimension(ireal,nobs):: diagbuf
real(r_single),allocatable,dimension(:,:,:)::rdiagbuf
integer(i_kind) i,ii,jj,iextra,ibin
- integer(i_kind) k,j,idia,irdim1,ioff0
+ integer(i_kind) k1,k2,k,j,idia,irdim1,ioff0,ioff1
integer(i_kind) isolz,iuse
integer(i_kind) mm1,itime,ilat,ilon,ilate,ilone,iozmr,ilev,ipres,iprcs,imls_levs
+ integer(i_kind) iairnd, iuvnd, ivisnd
integer(i_kind),dimension(iint,nobs):: idiagbuf
- integer(i_kind) iairnd,iuvnd,ivisnd
real(r_kind) gross,tnoise,pobs
+
character(12) string
character(10) filex
character(128) diag_ozone_file
@@ -1158,6 +1231,7 @@ subroutine setupozlev(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
mm1=mype+1
+ write(6,*)'emily checking: you are here ...', myname, obstype
!
!*********************************************************************************
@@ -1178,6 +1252,7 @@ subroutine setupozlev(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
irdim1=10
ioff0 = irdim1
if(lobsdiagsave) irdim1=irdim1+4*miter+1
+ ioff1 = irdim1
if (save_jacobian) then
nnz = 2 ! number of non-zero elements in dH(x)/dx profile
nind = 1
@@ -1273,6 +1348,12 @@ subroutine setupozlev(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
call tintrp2a1(ges_lnprsl,prsltmp,dlat,dlon,dtime,hrdifsig, &
nsig,mype,nfldsig)
+ ! GeoVaLs for JEDI/UFO
+ call tintrp2a1(ges_oz,ozgestmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(ges_prsi, prsitmp,dlat,dlon,dtime,hrdifsig,&
+ nsig+1,mype,nfldsig)
+
! Get approximate k value of surface by using surface pressure
! for surface check.
sfcchk=log(psges)
@@ -1304,22 +1385,25 @@ subroutine setupozlev(obsLL,odiagLL,lunin,mype,stats_oz,nlevs,nreal,nobs,&
! Check if observation above model top or below model surface
rlow=max(sfcchk-dpres,zero)
- rhgh=max(dpres-0.001_r_kind-float(nsig),zero)
+ rhgh=max(dpres-0.001_r_kind-real(nsig,r_kind),zero)
! calculate factor for error adjustment if too (high,low)
ratio_errors=obserror/(obserror+1.0e6_r_kind*rhgh+four*rlow)
! Check to see if observations is above the top of the model
- if (dpres > float(nsig)) then
+ if (dpres > real(nsig,r_kind)) then
ratio_errors=zero
obserror=1.0e6_r_kind
end if
+ call tintrp2a1(ges_oz,ozgestmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+
! Interpolate guess ozone to observation location and time
call tintrp31(ges_oz,o3ges,dlat,dlon,dpres,dtime, &
hrdifsig,mype,nfldsig)
iz = max(1, min( int(dpres), nsig))
- delz = max(zero, min(dpres - float(iz), one))
+ delz = max(zero, min(dpres - real(iz,r_kind), one))
if (save_jacobian) then
oz_ind = getindex(svars3d, 'oz')
if (oz_ind < 0) then
@@ -1627,7 +1711,7 @@ subroutine contents_binary_diag_(odiag)
rdiagbuf(10,1,ii) = visnd ! log10 ozone number density vis
if (lobsdiagsave) then
- idia=6
+ idia=ioff0
do jj=1,miter
idia=idia+1
if (odiag%muse(jj)) then
@@ -1649,6 +1733,7 @@ subroutine contents_binary_diag_(odiag)
rdiagbuf(idia,1,ii) = odiag%obssen(jj)
enddo
endif
+ idia = ioff1
if (save_jacobian) then
call writearray(dhx_dx, rdiagbuf(idia+1:irdim1,1,ii))
idia = idia + size(dhx_dx)
@@ -1659,34 +1744,52 @@ subroutine contents_netcdf_diag_(odiag)
type(obs_diag),pointer,intent(in):: odiag
! Observation class
character(7),parameter :: obsclass = ' ozlev'
+ integer(i_kind),parameter :: ione = 1
real(r_kind),dimension(miter) :: obsdiag_iuse
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
+ call nc_diag_metadata_to_single("Latitude", data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude", data(ilone,i) )
call nc_diag_metadata("MPI_Task_Number", mype )
- call nc_diag_metadata("Time", sngl(data(itime,i)-time_offset))
- call nc_diag_metadata("Inverse_Observation_Error", sngl(errorinv) )
- call nc_diag_metadata("Observation", sngl(ozlv) )
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ozone_inv) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted",sngl(ozone_inv) )
- call nc_diag_metadata("Reference_Pressure", sngl(preso3l) )
- call nc_diag_metadata("Input_Observation_Error", sngl(obserror) )
- if(obstype =="omps_lp")then
- call nc_diag_metadata("Log10 Air Number Density", sngl(airnd))
- call nc_diag_metadata("Log10 Ozone Number Density UV", sngl(uvnd))
- call nc_diag_metadata("Log10 Ozone Number Density VIS",sngl(visnd))
- endif
-
+ call nc_diag_metadata_to_single("Time", dtime,time_offset,'-' )
+ call nc_diag_metadata_to_single("Inverse_Observation_Error",errorinv )
+ call nc_diag_metadata_to_single("Observation", ozlv )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",ozone_inv )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted",ozone_inv )
+ call nc_diag_metadata_to_single("Reference_Pressure", preso3l*r100 ) ! Pa
if(luse(i)) then
- call nc_diag_metadata("Analysis_Use_Flag", 1 )
+ call nc_diag_metadata("Analysis_Use_Flag", ione )
else
- call nc_diag_metadata("Analysis_Use_Flag", -1 )
+ call nc_diag_metadata("Analysis_Use_Flag", -ione )
endif
+
+ call nc_diag_metadata_to_single("Input_Observation_Error",obserror )
+ if(obstype =="ompslp")then
+ call nc_diag_metadata_to_single("Log10 Air Number Density",airnd )
+ call nc_diag_metadata_to_single("Log10 Ozone Number Density UV",uvnd )
+ call nc_diag_metadata_to_single("Log10 Ozone Number Density VIS",visnd )
+ endif
+ call nc_diag_metadata_to_single("Forecast_adjusted", o3ppmv)
+ call nc_diag_metadata_to_single("Forecast_unadjusted", o3ppmv)
+ !if (wrtgeovals) then
+ ! ozgestmp = ozgestmp *constoz
+ ! call nc_diag_data2d("mole_fraction_of_ozone_in_air", ozgestmp)
+ ! call nc_diag_data2d("air_pressure",exp(prsltmp)*r1000) ! Pa
+ !endif
+ k1 = k
+ k2 = k - 1
+ if(k2 == 0)k2 = 1
+ if(k == nlevs)then
+ k1=nlevs-1
+ k2=1
+ endif
+
if (save_jacobian) then
call nc_diag_data2d("Observation_Operator_Jacobian_stind", dhx_dx%st_ind)
call nc_diag_data2d("Observation_Operator_Jacobian_endind", dhx_dx%end_ind)
call nc_diag_data2d("Observation_Operator_Jacobian_val", real(dhx_dx%val,r_single))
- endif
-
+ endif
+ ! GeoVaLs for JEDI/UFO
+ call nc_diag_data2d("mole_fraction_of_ozone_in_air", sngl(ozgestmp*constoz))
+ call nc_diag_data2d("air_pressure_levels",sngl(prsitmp*r1000))
if (lobsdiagsave) then
do jj=1,miter
if (odiag%muse(jj)) then
diff --git a/src/gsi/setuppblh.f90 b/src/gsi/setuppblh.f90
index 6d2a56b9fd..5a92494756 100644
--- a/src/gsi/setuppblh.f90
+++ b/src/gsi/setuppblh.f90
@@ -177,7 +177,7 @@ subroutine setuppblh(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diag
istnelv=14 ! index of station elevation (m)
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! Check for missing data !need obs value and error
diff --git a/src/gsi/setuppcp.f90 b/src/gsi/setuppcp.f90
index 970bc5b9af..7a89ccb6ca 100644
--- a/src/gsi/setuppcp.f90
+++ b/src/gsi/setuppcp.f90
@@ -223,7 +223,7 @@ subroutine setuppcp(obsLL,odiagLL,lunin,mype,aivals,nele,nobs,&
character(12) string
character(128) diag_pcp_file
- integer(i_kind) km1,mm1,iiflg,iextra,ireal
+ integer(i_kind) km1,mm1,iextra,ireal
integer(i_kind) ii,i,j,k,m,n,ibin,ioff,ioff0
integer(i_kind) ipt
integer(i_kind) nsphys,ixp,iyp,ixx,iyy
@@ -325,7 +325,6 @@ subroutine setuppcp(obsLL,odiagLL,lunin,mype,aivals,nele,nobs,&
! ONE TIME, INITIAL SETUP PRIOR TO PROCESSING SATELLITE DATA
!
! Initialize variables
- iiflg = 1
ncloud = ncld
nsphys = max(int(two*deltim/dtphys+0.9999_r_kind),1)
dtp = two*deltim/nsphys
@@ -417,8 +416,8 @@ subroutine setuppcp(obsLL,odiagLL,lunin,mype,aivals,nele,nobs,&
elseif (amsu) then
itype = 8
endif
- rterm1=one/float(nsig)
- rterm2=one/float(nsig*(nsig-1))
+ rterm1=one/real(nsig,r_kind)
+ rterm2=one/real(nsig*(nsig-1),r_kind)
call dtime_setup()
do n = 1,nobs
diff --git a/src/gsi/setuppm2_5.f90 b/src/gsi/setuppm2_5.f90
index 79e6129cd8..ad940cce78 100644
--- a/src/gsi/setuppm2_5.f90
+++ b/src/gsi/setuppm2_5.f90
@@ -94,8 +94,8 @@ subroutine setuppm2_5(obsLL,odiagLL,lunin,mype,nreal,nobs,isis,is,conv_diagsave)
use gsi_4dvar, only: nobs_bins,hr_obsbin
use gridmod, only : get_ij,get_ijk
-
use guess_grids, only : nfldsig,hrdifsig
+ use guess_grids, only : veg_type
use gsi_bundlemod, only : gsi_bundlegetpointer,GSI_BundlePrint
use gsi_chemguess_mod, only : gsi_chemguess_get,gsi_chemguess_bundle
use gsi_metguess_mod, only : gsi_metguess_get,gsi_metguess_bundle
@@ -115,7 +115,8 @@ subroutine setuppm2_5(obsLL,odiagLL,lunin,mype,nreal,nobs,isis,is,conv_diagsave)
use chemmod, only: naero_gocart_wrf,aeronames_gocart_wrf,&
upper2lower,lower2upper,laeroana_gocart,wrf_pm2_5
use chemmod, only: naero_cmaq_fv3,aeronames_cmaq_fv3,imodes_cmaq_fv3,laeroana_fv3cmaq
- use chemmod, only: naero_smoke_fv3,aeronames_smoke_fv3,laeroana_fv3smoke,pm2_5_innov_threshold
+ use chemmod, only: naero_smoke_fv3,aeronames_smoke_fv3,laeroana_fv3smoke
+ use chemmod, only: pm2_5_innov_threshold,pm2_5_urban_innov_threshold,pm2_5_bg_threshold
use gridmod, only : cmaq_regional,wrf_mass_regional,fv3_cmaq_regional
implicit none
@@ -146,7 +147,7 @@ subroutine setuppm2_5(obsLL,odiagLL,lunin,mype,nreal,nobs,isis,is,conv_diagsave)
real(r_kind) :: pm2_5ges
real(r_kind) :: ratio_errors,error
real(r_kind) :: innov,innov_error2,rwgt,valqc,tfact,innov_error,elevges,&
- elevdiff,conc,elevobs,ps_ges,site_id,tv_ges
+ elevdiff,conc,elevobs,ps_ges,site_id,tv_ges,veg_type_ges
real(r_kind) errinv_input,errinv_adjst,errinv_final
real(r_kind) err_input,err_adjst,err_final
@@ -278,7 +279,7 @@ subroutine setuppm2_5(obsLL,odiagLL,lunin,mype,nreal,nobs,isis,is,conv_diagsave)
call stop2(453)
endif
- do i=2,naero_smoke_fv3
+ do i=2,naero_smoke_fv3-1 ! remove contribution from coarsepm
aeroname=trim(aeronames_smoke_fv3(i))
call gsi_bundlegetpointer(gsi_chemguess_bundle(1),trim(aeroname),&
rank3,ier)
@@ -705,13 +706,18 @@ subroutine setuppm2_5(obsLL,odiagLL,lunin,mype,nreal,nobs,isis,is,conv_diagsave)
if (wrf_mass_regional .or. fv3_cmaq_regional .or. laeroana_fv3smoke) then
call tintrp2a11(ges_ps,ps_ges,dlat,dlon,dtime,hrdifsig,&
mype,nfldsig)
-
call tintrp2a11(ges_tv(:,:,1,nfldsig),tv_ges,dlat,dlon,dtime,hrdifsig,&
mype,nfldsig)
conc=conc/(ps_ges*r1000/(rd*tv_ges))
endif
-
-
+!
+ if (laeroana_fv3smoke) then
+ if (.not. allocated(veg_type)) then
+ print*,"VEG_TYPE NOT ALLOCATED, WILL NOT BE USED IN PM2.5 DA FOR RRFS_SD",mype
+ else
+ call intrp2a11(veg_type(:,:,1),veg_type_ges,dlat,dlon,mype)
+ endif
+ endif
!if elevobs is known than calculate difference otherwise
!assume that difference is acceptable
@@ -740,17 +746,20 @@ subroutine setuppm2_5(obsLL,odiagLL,lunin,mype,nreal,nobs,isis,is,conv_diagsave)
mype,nfldsig)
innov = conc - pm2_5ges
if (laeroana_fv3smoke) then
- if ( -1.0*innov >= pm2_5_innov_threshold .or. &
- (innov > pm2_5_innov_threshold .and. pm2_5ges >=1.0_r_kind).or. &
- (conc >= 40.0_r_kind .and. pm2_5ges >=1.0_r_kind).or. &
- conc >= 100.0_r_kind ) then
- innov = innov
+ if ( veg_type_ges == 13.0_r_kind ) then
+ if (abs(innov) < pm2_5_urban_innov_threshold) then
+ muse(i)=.false.
+ end if
else
- innov = 0.0_r_kind
+ if (abs(innov) < pm2_5_innov_threshold) then
+ muse(i)=.false.
+ end if
+ end if
+
+ if (pm2_5ges < pm2_5_bg_threshold) then
muse(i)=.false.
end if
if (tv_ges-273.15_r_kind < 5.0_r_kind) then
- innov = 0.0_r_kind
muse(i)=.false.
end if
@@ -770,21 +779,28 @@ subroutine setuppm2_5(obsLL,odiagLL,lunin,mype,nreal,nobs,isis,is,conv_diagsave)
mype,nfldsig)
call tintrp2a11(pm25wc(:,:,:,2,nfldsig),pm25wc_ges(2),dlat,dlon,dtime,hrdifsig,&
mype,nfldsig)
-
- if (pm25wc_ges(1) >= 1.0_r_kind) then
+ if (pm25wc_ges(1) >= pm2_5_bg_threshold) then
pm25wc_ges(1)=1.0_r_kind
else
- pm25wc_ges(2)=0.0_r_kind
+ pm25wc_ges(1)=0.0_r_kind
end if
- if (pm25wc_ges(2) >= 1.0_r_kind) then
+ if (pm25wc_ges(2) >= pm2_5_bg_threshold) then
pm25wc_ges(2)=1.0_r_kind
else
pm25wc_ges(2)=0.0_r_kind
end if
+ if ( (pm25wc_ges(1)+pm25wc_ges(2)) < 1.0_r_kind ) then
+ muse(i) = .false.
+ end if
else
pm25wc_ges = 0.0_r_kind
end if
+ if (oneobtest_chem) then
+ pm25wc_ges=1.0_r_kind
+ muse(i) = .true.
+ end if
+
error=one/data(ierror,i)
ratio_errors=one/sqrt(real(dup(i)))
innov_error = error*innov
@@ -1115,6 +1131,7 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_metadata("Latitude", data(ilate,i) )
call nc_diag_metadata("Longitude", data(ilone,i) )
call nc_diag_metadata("Station_Elevation", data(ielev,i) )
+ call nc_diag_metadata("Station_Veg_Type", veg_type_ges )
call nc_diag_metadata("Pressure", ps_ges )
call nc_diag_metadata("Height", data(ielev,i) )
call nc_diag_metadata("Time", dtime-time_offset )
diff --git a/src/gsi/setuppmsl.f90 b/src/gsi/setuppmsl.f90
index d66a6f827e..b830d26b97 100644
--- a/src/gsi/setuppmsl.f90
+++ b/src/gsi/setuppmsl.f90
@@ -191,7 +191,7 @@ subroutine setuppmsl(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diag
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
dup=one
diff --git a/src/gsi/setupps.f90 b/src/gsi/setupps.f90
index 6a0fdd4fb2..fde1f540ba 100644
--- a/src/gsi/setupps.f90
+++ b/src/gsi/setupps.f90
@@ -125,15 +125,16 @@ subroutine setupps(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsa
use obsmod, only: netcdf_diag, binary_diag, dirname
use obsmod, only: l_obsprvdiag
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim, nc_diag_read_close
use gridmod, only: nsig,get_ij,twodvar_regional
use constants, only: zero,one_tenth,one,half,pi,g_over_rd, &
huge_r_kind,tiny_r_kind,two,huge_single, &
- r1000,wgtlim,tiny_single,r10,three
+ r1000,r100,wgtlim,tiny_single,r10,three
use jfunc, only: jiter,last,jiterstart,miter
use qcmod, only: dfact,dfact1,npres_print,vqc,nvqc
use guess_grids, only: hrdifsig,ges_lnprsl,nfldsig,ntguessig
+ use guess_grids, only: geop_hgtl, ges_prsi, ges_tsen
use convinfo, only: nconvtype,cermin,cermax,cgross,cvar_b,cvar_pg,ictype,icsubtype
use convinfo, only: ibeta,ikapa
@@ -181,15 +182,26 @@ subroutine setupps(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsa
real(r_kind) cg_t,cvar,wgt,rat_err2,qcgross
real(r_kind),dimension(nobs):: dup
real(r_kind),dimension(nsig):: prsltmp
+ real(r_kind),dimension(nsig):: zges, prsltmp2, tvgestmp, tsentmp, qtmp, utmp, vtmp
+ real(r_kind) :: tgges,roges
+ real(r_kind),dimension(nsig+1):: prsitmp
real(r_kind),dimension(nele,nobs):: data
real(r_single),allocatable,dimension(:,:)::rdiagbuf
+ ! GSI profiles are stored with bottom up index; output the profiles
+ ! with top down index
+ real(r_kind),dimension(nsig):: ttmp_reverse,tvtmp_reverse,qtmp_reverse,utmp_reverse,vtmp_reverse
+ real(r_kind),dimension(nsig):: zges_reverse,prsltmp2_reverse
+ real(r_kind),dimension(nsig):: zges_read_reverse, zges_geometric_reverse
+ real(r_kind),dimension(nsig+1):: prsitmp_reverse
+ !<< JEDI
integer(i_kind) ier,ilon,ilat,ipres,ihgt,itemp,id,itime,ikx,iqc,iptrb,ijb
integer(i_kind) ier2,iuse,ilate,ilone,istnelv,idomsfc,izz,iprvd,isprvd
integer(i_kind) ikxx,nn,ibin,ioff,ioff0
- integer(i_kind) i,j,nchar,nreal,ii,jj,k,l,mm1
+ integer(i_kind) i,j,nchar,nreal,ii,jj,k,kk,l,mm1
integer(i_kind) itype,isubtype
integer(i_kind) ibb,ikk,idddd
+ integer(i_kind) msges
logical,dimension(nobs):: luse,muse
integer(i_kind),dimension(nobs):: ioid ! initial (pre-distribution) obs ID
@@ -214,6 +226,8 @@ subroutine setupps(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsa
real(r_kind),allocatable,dimension(:,:,: ) :: ges_ps
real(r_kind),allocatable,dimension(:,:,: ) :: ges_z
real(r_kind),allocatable,dimension(:,:,:,:) :: ges_tv
+ real(r_kind),allocatable,dimension(:,:,:,:) :: ges_q
+ real(r_kind),allocatable,dimension(:,:,:,:) :: ges_u, ges_v
type(sparr2) :: dhx_dx
integer(i_kind) :: ps_ind, nnz, nind
@@ -273,7 +287,7 @@ subroutine setupps(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsa
! muse = true then used
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! If HD raobs available move prepbufr version to monitor
if(nhdps > 0)then
@@ -298,26 +312,26 @@ subroutine setupps(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsa
hr_offset=min_offset/60.0_r_kind
! Check for duplicate observations at same location
dup=one
- do k=1,nobs
- do l=k+1,nobs
- if(data(ilat,k) == data(ilat,l) .and. &
- data(ilon,k) == data(ilon,l) .and. &
- data(ier,k) < r1000 .and. data(ier,l) < r1000 .and. &
- muse(k) .and. muse(l))then
- if(l_closeobs) then
- if(abs(data(itime,k)-hr_offset)>emily
+ do k = 1, nsig
+ kk = nsig-k+1
+ utmp_reverse(kk) = utmp(k)
+ vtmp_reverse(kk) = vtmp(k)
+ ttmp_reverse(kk) = tsentmp(k)
+ tvtmp_reverse(kk) = tvgestmp(k) !emily
+ qtmp_reverse(kk) = qtmp(k)
+ !hsges_reverse(kk) = hsges(k)
+ !zges_read_reverse(kk)= zges_read(k)
+ !zges_geometric_reverse(kk)= zges_geometric(k)
+ zges_read_reverse(kk)= zsges+zges(k)
+ !zges_geometric_reverse(kk)= zges_geometric(k)
+ zges_reverse(kk) = zges(k)
+ prsltmp2_reverse(kk) = prsltmp2(k)
+ enddo
+ do k = 1, nsig+1
+ kk = (nsig+1)-k+1
+ prsitmp_reverse(kk) = prsitmp(k)
+ enddo
+ call nc_diag_data2d("atmosphere_pressure_coordinate", sngl(prsltmp2_reverse*r1000))
+ call nc_diag_data2d("atmosphere_pressure_coordinate_interface", sngl(prsitmp_reverse*r1000))
+ call nc_diag_data2d("air_temperature", sngl(ttmp_reverse))
+ call nc_diag_data2d("virtual_temperature", sngl(tvtmp_reverse)) !emily
+ call nc_diag_data2d("specific_humidity", sngl(qtmp_reverse))
+ call nc_diag_data2d("eastward_wind", sngl(utmp_reverse))
+ call nc_diag_data2d("northward_wind", sngl(vtmp_reverse))
+! call nc_diag_data2d("geopotential_height", sngl(hsges_reverse) ) !orig
+ call nc_diag_data2d("geopotential_height", sngl(zges_read_reverse) ) !emily
+ !call nc_diag_data2d("geometric_height", sngl(zges_geometric_reverse) )
+ !!emily
+ !< obsLL(:)
save_jacobian = conv_diagsave .and. jiter==jiterstart .and. lobsdiag_forenkf
@@ -320,9 +352,12 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
icat =22 ! index of data level category
ijb =23 ! index of non linear qc parameter
iptrb=24 ! index of q perturbation
+ if (l_rtma3d .or. twodvar_regional) then
+ iqt =25 ! index of flag indicating if virtual temp is associated to this moisture obs
+ end if
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! If HD raobs available move prepbufr version to monitor
if(nhdq > 0)then
@@ -359,8 +394,11 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
hr_offset=min_offset/60.0_r_kind
dup=one
do k=1,nobs
+ ikx=nint(data(ikxx,k))
+ itype=ictype(ikx)
+ landsfctype =( itype==181 .or. itype==183 .or. itype==187 )
do l=k+1,nobs
- if (twodvar_regional) then
+ if (twodvar_regional .or. (hofx_2m_sfcfile .and. landsfctype) ) then
duplogic=data(ilat,k) == data(ilat,l) .and. &
data(ilon,k) == data(ilon,l) .and. &
data(ier,k) < r1000 .and. data(ier,l) < r1000 .and. &
@@ -398,6 +436,7 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
iip=0
nchar=1
ioff0=21
+ if (l_rtma3d .or. twodvar_regional) ioff0 = ioff0 + 2 ! 22:tdry; 23:tvflag (in binary obsdiag for 2D/3DRTMA)
nreal=ioff0
if (lobsdiagsave) nreal=nreal+4*miter+1
if (twodvar_regional .or. l_obsprvdiag) then
@@ -425,9 +464,15 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
ice=.false. ! get larger (in rh) q obs error for mixed and ice phases
iderivative=0
+
+ ! calculate qsat and 2m qsat
do jj=1,nfldsig
- call genqsat(qg(1,1,1,jj),ges_tsen(1,1,1,jj),ges_prsl(1,1,1,jj),lat2,lon2,nsig,ice,iderivative)
- qg2m(:,:,jj)=qg(:,:,1,jj)
+ call genqsat(qg(:,:,:,jj),ges_tsen(:,:,:,jj),ges_prsl(:,:,:,jj),lat2,lon2,nsig,ice,iderivative)
+ if (i_use_2mq4b > 0) then ! use lowest model level
+ qg2m(:,:,jj)=qg(:,:,1,jj)
+ elseif ( hofx_2m_sfcfile ) then ! calculate from 2m model output
+ call genqsat(qg2m(:,:,jj),ges_t2m(:,:,jj),ges_ps(:,:,jj),lat2,lon2,1,ice,iderivative)
+ endif
end do
@@ -440,10 +485,10 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
call dtime_check(dtime, in_curbin, in_anybin)
if(.not.in_anybin) cycle
+ landsfctype =( itype==181 .or. itype==183 .or. itype==187 )
! Flag static conditions to create PBL_pseudo_surfobsq obs.
- l_pbl_pseudo_itype = l_pbl_pseudo_surfobsq .and. &
- ( itype==181 .or. itype==183 .or.itype==187 )
+ l_pbl_pseudo_itype = l_pbl_pseudo_surfobsq .and. landsfctype
if(in_curbin) then
! Convert obs lats and lons to grid coordinates
@@ -506,27 +551,50 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
call tintrp2a1(ges_lnprsl,prsltmp,dlat,dlon,dtime,hrdifsig,&
nsig,mype,nfldsig)
+
+
+! GEOVALS for UFO eval
+ psges2 = psges ! keep in cb
+ prsltmp2 = exp(prsltmp)
+ call tintrp2a1(ges_prsi,prsitmp,dlat,dlon,dtime,hrdifsig,&
+ nsig+1,mype,nfldsig)
+ call tintrp2a1(ges_tsen,ttmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(ges_q,qtmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(ges_u,utmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(ges_v,vtmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(geop_hgtl,hsges,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+
+! END GEOVALS
presq=r10*exp(dpres)
itype=ictype(ikx)
dprpx=zero
- if(((itype > 179 .and. itype < 190) .or. itype == 199) &
+
+ if ( hofx_2m_sfcfile .and. landsfctype) then
+ dpres = one ! put obs on surface
+ else
+ if(((itype > 179 .and. itype < 190) .or. itype == 199) &
.and. .not.twodvar_regional)then
- dprpx=abs(one-exp(dpres-log(psges)))*r10
- end if
+ dprpx=abs(one-exp(dpres-log(psges)))*r10
+ endif
! Put obs pressure in correct units to get grid coord. number
- call grdcrd1(dpres,prsltmp(1),nsig,-1)
+ call grdcrd1(dpres,prsltmp(1),nsig,-1)
! Get approximate k value of surface by using surface pressure
- sfcchk=log(psges)
- call grdcrd1(sfcchk,prsltmp(1),nsig,-1)
+ sfcchk=log(psges)
+ call grdcrd1(sfcchk,prsltmp(1),nsig,-1)
! Check to see if observations is above the top of the model (regional mode)
- if( dpres>=nsig+1)dprpx=1.e6_r_kind
- if((itype > 179 .and. itype < 186) .or. itype == 199) dpres=one
+ if( dpres>=nsig+1)dprpx=1.e6_r_kind
+ if((itype > 179 .and. itype < 186) .or. itype == 199) dpres=one
+
+ endif
-! Scale errors by guess saturation q
-
qob = data(iqob,i)
if(limitqobs) then
call tintrp31(ges_qsat,qsges,dlat,dlon,dpres,dtime,hrdifsig,&
@@ -534,11 +602,13 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
qob=min(qob,superfact*qsges)
end if
+! get qsges, to be used to scale the obs error
call tintrp31(qg,qsges,dlat,dlon,dpres,dtime,hrdifsig,&
mype,nfldsig)
-! Interpolate 2-m qs to obs locations/times
- if((i_use_2mq4b > 0) .and. ((itype > 179 .and. itype < 190) .or. itype == 199) &
- .and. .not.twodvar_regional)then
+
+! overwrite qsges with 2-m qs if sfc obs scheme
+ if( ( (i_use_2mq4b > 0) .and. ((itype > 179 .and. itype < 190) .or. itype == 199) &
+ .and. .not.twodvar_regional) .or. (hofx_2m_sfcfile .and. landsfctype) )then
call tintrp2a11(qg2m,qsges,dlat,dlon,dtime,hrdifsig,mype,nfldsig)
endif
@@ -549,10 +619,36 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
rmaxerr=max(small2,rmaxerr)
errorx =(data(ier,i)+dprpx)*qsges
-! Interpolate guess moisture to observation location and time
- call tintrp31(ges_q,qges,dlat,dlon,dpres,dtime, &
- hrdifsig,mype,nfldsig)
-
+! qges: Interpolate guess moisture to observation location and time
+
+ if (.not. ( hofx_2m_sfcfile .and. landsfctype) ) then
+ call tintrp31(ges_q,qges,dlat,dlon,dpres,dtime, &
+ hrdifsig,mype,nfldsig)
+ else
+ ! only use land locations
+ if (int(data(idomsfc,i)) .NE. 1 ) muse(i) = .false.
+
+ call tintrp2a11(ges_q2m,qges,dlat,dlon,dtime,hrdifsig,mype,nfldsig)
+
+ ! terrain correction: assume RH_zo = RH_zm, and correct T with
+ ! same lapse rate as used for T2m terrain correction
+
+ delta_z = data(istnelv,i) - data(izz,i) ! obs -model
+
+ do jj=1,nfldsig
+ ! qsat in model at height of obs
+ call genqsat(qg2m_o(:,:,jj),ges_t2m(:,:,jj)+delta_z*T_lapse,ges_ps(:,:,jj),lat2,lon2,1,ice,iderivative)
+ enddo
+
+ call tintrp2a11(qg2m_o,qsges_o,dlat,dlon,dtime,hrdifsig,mype,nfldsig)
+ q_delta_terrain = (qsges/qsges_o - 1)*qob
+ qob = qob * ( qsges/qsges_o)
+
+ !update the station elevation
+ data(istnelv,i) = data(izz,i)
+
+ endif
+
ddiff=qob-qges
! Setup dynamic ob error specification for aircraft recon in hurricanes
@@ -572,18 +668,22 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
endif
errorx =max(small1,errorx)
-
! Adjust observation error to reflect the size of the residual.
! If extrapolation occurred, then further adjust error according to
! amount of extrapolation.
- rlow=max(sfcchk-dpres,zero)
+ if (.not. (hofx_2m_sfcfile .and. landsfctype) ) then
+ rlow=max(sfcchk-dpres,zero)
! linear variation of observation ramp [between grid points 1(~3mb) and 15(~45mb) below the surface]
- if(l_sfcobserror_ramp_q) then
- ramp=min(max(((rlow-1.0_r_kind)/(15.0_r_kind-1.0_r_kind)),0.0_r_kind),1.0_r_kind)*0.001_r_kind
+ if(l_sfcobserror_ramp_q) then
+ ramp=min(max(((rlow-1.0_r_kind)/(15.0_r_kind-1.0_r_kind)),0.0_r_kind),1.0_r_kind)*0.001_r_kind
+ else
+ ramp=rlow
+ endif
else
- ramp=rlow
+ rlow = zero
+ ramp = zero
endif
rhgh=max(dpres-r0_001-rsig,zero)
@@ -594,14 +694,27 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
if(rhgh/=zero) awork(3) = awork(3) + one
end if
- ratio_errors=error*qsges/(errorx+1.0e6_r_kind*rhgh+r8*ramp)
+! inflate error for uncertainty in the terrain adjustment
+ lapse_error = 0.
+ if ( hofx_2m_sfcfile .and. landsfctype) then
+ if (abs(delta_z)max_delta_z do not assim.
+ ! inflate obs error to account for error in lapse_rate
+ ! also include some representativity error here (assuming
+ ! delta_z ~ heterogeneity)
+ lapse_error = abs(lapse_error_frac*q_delta_terrain)
+ else
+ muse(i)=.false.
+ endif
+ endif
+
+ ratio_errors=error*qsges/(errorx+1.0e6_r_kind*rhgh+r8*ramp + lapse_error)
! Check to see if observations is above the top of the model (regional mode)
if (dpres > rsig) ratio_errors=zero
error=one/(error*qsges)
iz = max(1, min( int(dpres), nsig))
- delz = max(zero, min(dpres - float(iz), one))
+ delz = max(zero, min(dpres - real(iz,r_kind), one))
if (save_jacobian) then
@@ -618,7 +731,7 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
dhx_dx%val(2) = delz ! weight for iz+1's level
endif
-! Interpolate 2-m q to obs locations/times
+! i_use_2mq4b: Interpolate 2-m q to obs locations/times
if(i_use_2mq4b>0 .and. itype > 179 .and. itype < 190 .and. .not.twodvar_regional)then
if(i_coastline==2 .or. i_coastline==3) then
@@ -643,7 +756,7 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
call stop2(100)
endif
ddiff=qob-qges
- endif
+ endif ! i_use_2mq4b
! If requested, setup for single obs test.
@@ -943,7 +1056,7 @@ subroutine setupq(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
my_head => null()
ENDDO
- endif ! 181,183,187
+ endif ! l_pbl_pseudo_itype
!!!!!!!!!!!!!!!!!! PBL pseudo surface obs !!!!!!!!!!!!!!!!!!!!!!!
! End of loop over observations
@@ -1025,7 +1138,7 @@ subroutine init_vars_
call stop2(999)
endif
! get q2m ...
- if (i_use_2mq4b>0) then
+ if (i_use_2mq4b>0 .or. hofx_2m_sfcfile) then
varname='q2m'
call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank2,istatus)
if (istatus==0) then
@@ -1044,6 +1157,61 @@ subroutine init_vars_
call stop2(999)
endif
endif ! i_use_2mq4b
+ if (hofx_2m_sfcfile) then
+ varname='t2m'
+ call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank2,istatus)
+ if (istatus==0) then
+ if(allocated(ges_t2m))then
+ write(6,*) trim(myname), ': ', trim(varname), ' already incorrectly alloc '
+ call stop2(999)
+ endif
+ allocate(ges_t2m(size(rank2,1),size(rank2,2),nfldsig))
+ ges_t2m(:,:,1)=rank2
+ do ifld=2,nfldsig
+ call gsi_bundlegetpointer(gsi_metguess_bundle(ifld),trim(varname),rank2,istatus)
+ ges_t2m(:,:,ifld)=rank2
+ enddo
+ else
+ write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
+ call stop2(999)
+ endif
+ endif ! hofx_2m_sfcfile
+! get u ...
+ varname='u'
+ call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank3,istatus)
+ if (istatus==0) then
+ if(allocated(ges_u))then
+ write(6,*) trim(myname), ': ', trim(varname), ' already incorrectly alloc '
+ call stop2(999)
+ endif
+ allocate(ges_u(size(rank3,1),size(rank3,2),size(rank3,3),nfldsig))
+ ges_u(:,:,:,1)=rank3
+ do ifld=2,nfldsig
+ call gsi_bundlegetpointer(gsi_metguess_bundle(ifld),trim(varname),rank3,istatus)
+ ges_u(:,:,:,ifld)=rank3
+ enddo
+ else
+ write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
+ call stop2(999)
+ endif
+! get v ...
+ varname='v'
+ call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank3,istatus)
+ if (istatus==0) then
+ if(allocated(ges_v))then
+ write(6,*) trim(myname), ': ', trim(varname), ' already incorrectly alloc '
+ call stop2(999)
+ endif
+ allocate(ges_v(size(rank3,1),size(rank3,2),size(rank3,3),nfldsig))
+ ges_v(:,:,:,1)=rank3
+ do ifld=2,nfldsig
+ call gsi_bundlegetpointer(gsi_metguess_bundle(ifld),trim(varname),rank3,istatus)
+ ges_v(:,:,:,ifld)=rank3
+ enddo
+ else
+ write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
+ call stop2(999)
+ endif
! get q ...
varname='q'
call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank3,istatus)
@@ -1140,6 +1308,11 @@ subroutine contents_binary_diag_(odiag)
rdiagbuf(20,ii) = qsges ! guess saturation specific humidity
rdiagbuf(21,ii) = 1e+10_r_single ! spread (filled in by EnKF)
+ if (l_rtma3d .or. twodvar_regional) then ! in binary obsdiag for 2D/3DRTMA
+ rdiagbuf(22,ii) = data(itemp,i) ! dry temperature associated to qob
+ rdiagbuf(23,ii) = data(iqt, i) ! tv flag (0: virtual temp; 1: sensible temp)
+ end if
+
ioff=ioff0
if (lobsdiagsave) then
do jj=1,miter
@@ -1217,6 +1390,11 @@ subroutine contents_binary_diagp_(odiag)
rdiagbufp(20,iip) = qsges ! guess saturation specific humidity
rdiagbufp(21,iip) = 1e+10_r_single ! spread (filled in by EnKF)
+ if (l_rtma3d .or. twodvar_regional) then ! in binary obsdiag for 2D/3DRTMA
+ rdiagbufp(22,ii) = data(itemp,i) ! dry temperature associated to qob
+ rdiagbufp(23,ii) = data(iqt, i) ! tv flag (0: virtual temp; 1: sensible temp)
+ end if
+
ioff=ioff0
!----
if (lobsdiagsave) then
@@ -1270,29 +1448,36 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_metadata("Observation_Class", obsclass )
call nc_diag_metadata("Observation_Type", ictype(ikx) )
call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
- call nc_diag_metadata("Station_Elevation", sngl(data(istnelv,i)) )
- call nc_diag_metadata("Pressure", sngl(presq) )
- call nc_diag_metadata("Height", sngl(data(iobshgt,i)) )
- call nc_diag_metadata("Time", sngl(dtime-time_offset))
- call nc_diag_metadata("Prep_QC_Mark", sngl(data(iqc,i)) )
- call nc_diag_metadata("Prep_Use_Flag", sngl(data(iuse,i)) )
- call nc_diag_metadata("Nonlinear_QC_Var_Jb", sngl(var_jb) )
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
+ call nc_diag_metadata_to_single("Latitude", data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude", data(ilone,i) )
+! this is the obs height after being interpolated to the model (=model height)
+ call nc_diag_metadata_to_single("Station_Elevation",data(istnelv,i) )
+ call nc_diag_metadata_to_single("Pressure", presq )
+! this is the original obs height (= stn elevation, before being interpolated)
+ call nc_diag_metadata_to_single("Height", data(iobshgt,i) )
+ call nc_diag_metadata_to_single("Time", dtime,time_offset,'-' )
+ call nc_diag_metadata_to_single("Prep_QC_Mark", data(iqc,i) )
+ call nc_diag_metadata_to_single("Prep_Use_Flag",data(iuse,i) )
+ call nc_diag_metadata_to_single("Nonlinear_QC_Var_Jb",var_jb )
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",rwgt )
if(muse(i)) then
- call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
+ call nc_diag_metadata("Analysis_Use_Flag", 1.0_r_single )
else
- call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
+ call nc_diag_metadata("Analysis_Use_Flag", -1.0_r_single )
endif
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
-
- call nc_diag_metadata("Observation", sngl(data(iqob,i)))
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ddiff) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(qob-qges) )
- call nc_diag_metadata("Forecast_Saturation_Spec_Hum", sngl(qsges) )
+ call nc_diag_metadata_to_single("Errinv_Input", errinv_input )
+ call nc_diag_metadata_to_single("Errinv_Adjust",errinv_adjst )
+ call nc_diag_metadata_to_single("Errinv_Final", errinv_final )
+
+ call nc_diag_metadata_to_single("Observation", data(iqob,i) )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",ddiff )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted",qob,qges,'-')
+ call nc_diag_metadata_to_single("Forecast_Saturation_Spec_Hum",qsges )
+ if (l_rtma3d .or. twodvar_regional) then
+ call nc_diag_metadata_to_single("Observation_Tdry", data(itemp,i) )
+ call nc_diag_metadata_to_single("Setup_QC_Mark", data(iqt, i) )
+ endif
+
if (lobsdiagsave) then
do jj=1,miter
if (odiag%muse(jj)) then
@@ -1305,14 +1490,14 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_data2d("ObsDiagSave_iuse", obsdiag_iuse )
call nc_diag_data2d("ObsDiagSave_nldepart", odiag%nldepart )
call nc_diag_data2d("ObsDiagSave_tldepart", odiag%tldepart )
- call nc_diag_data2d("ObsDiagSave_obssen", odiag%obssen )
+ call nc_diag_data2d("ObsDiagSave_obssen", odiag%obssen )
endif
if (twodvar_regional .or. l_obsprvdiag) then
call nc_diag_metadata("Dominant_Sfc_Type", data(idomsfc,i) )
call nc_diag_metadata("Model_Terrain", data(izz,i) )
r_prvstg = data(iprvd,i)
- call nc_diag_metadata("Provider_Name", c_prvstg )
+ call nc_diag_metadata("Provider_Name", c_prvstg )
r_sprvstg = data(isprvd,i)
call nc_diag_metadata("Subprovider_Name", c_sprvstg )
endif
@@ -1322,6 +1507,40 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_data2d("Observation_Operator_Jacobian_val", real(dhx_dx%val,r_single))
endif
+ ! GEOVALS
+ !>>emily
+ do k = 1, nsig
+ kk = nsig-k+1
+ utmp_reverse(kk) = utmp(k)
+ vtmp_reverse(kk) = vtmp(k)
+ ttmp_reverse(kk) = ttmp(k)
+ !tvtmp_reverse(kk) = tges(k) !emily
+ qtmp_reverse(kk) = qtmp(k)
+ hsges_reverse(kk) = hsges(k)
+! zges_read_reverse(kk)= zges_read(k)
+! zges_geometric_reverse(kk)= zges_geometric(k)
+ !zges_reverse(kk) = zges(k)
+ prsltmp2_reverse(kk) = prsltmp2(k)
+ enddo
+ do k = 1, nsig+1
+ kk = (nsig+1)-k+1
+ prsitmp_reverse(kk) = prsitmp(k)
+ enddo
+ call nc_diag_data2d("atmosphere_pressure_coordinate", sngl(prsltmp2_reverse*r1000))
+ call nc_diag_data2d("atmosphere_pressure_coordinate_interface", sngl(prsitmp_reverse*r1000))
+ call nc_diag_data2d("air_temperature", sngl(ttmp_reverse))
+ call nc_diag_data2d("virtual_temperature", sngl(tvtmp_reverse)) !emily
+ call nc_diag_data2d("specific_humidity", sngl(qtmp_reverse))
+ call nc_diag_data2d("eastward_wind", sngl(utmp_reverse))
+ call nc_diag_data2d("northward_wind", sngl(vtmp_reverse))
+ call nc_diag_data2d("geopotential_height", sngl(hsges_reverse)) !orig
+! call nc_diag_data2d("geopotential_height", sngl(zges_read_reverse)) !emily
+! call nc_diag_data2d("geometric_height", sngl(zges_geometric_reverse)) !emily
+ !< nchanl)then
@@ -551,19 +581,20 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
end if
! Load channel numbers into local array based on satellite type
+ if (iuse_rad(j)==4) then
+ predx(:,j)=zero
+ endif
ich(jc)=j
do i=1,npred
- if (iuse_rad(j)==4) predx(i,j)=zero
predchan(i,jc)=predx(i,j)
end do
!
! Set error instrument channels
tnoise(jc)=varch(j)
- channel_passive=iuse_rad(j)==-1 .or. iuse_rad(j)==0
- if (iuse_rad(j)< -1 .or. (channel_passive .and. &
+ if (iuse_rad(j)< -1 .or. (channel_passive(j) .and. &
.not.rad_diagsave)) tnoise(jc)=r1e10
- if (passive_bc .and. channel_passive) tnoise(jc)=varch(j)
+ if (passive_bc .and. channel_passive(j)) tnoise(jc)=varch(j)
if (iuse_rad(j)>0) l_may_be_passive=.true.
if (tnoise(jc) < 1.e4_r_kind) toss = .false.
@@ -589,6 +620,26 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
return
endif
+! Load data array for current satellite
+ read(lunin) data_s,luse,ioid
+
+ if (nobskeep>0) then
+! write(6,*)'setuprad: nobskeep',nobskeep
+ call stop2(275)
+ end if
+
+ call dtime_setup()
+! If using CADS setup arrays and calculate imager BTs
+ imager_cluster_fraction=zero
+ imager_cluster_bt=zero
+ imager_chan_stdev=zero
+ imager_model_bt=zero
+ if ((iasi_cads .and. iasi) .or. (cris_cads .and. cris)) then
+
+ call cads_imager_calc(obstype,isis,nobs,nreal,nchanl,nsig,data_s,init_pass,mype, &
+ imager_cluster_fraction,imager_cluster_bt,imager_chan_stdev, imager_model_bt)
+ endif ! using cads
+
if ( mype == 0 .and. .not.l_may_be_passive) write(6,*)mype,'setuprad: passive obs',is,isis
! Logic to turn off print of reading coefficients if not first interation or not mype_diaghdr or not init_pass
@@ -695,8 +746,6 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
endif
endif
-
-
! Find number of channels written to diag file
if(reduce_diag)then
nchanl_diag=0
@@ -766,14 +815,6 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
if (netcdf_diag) call init_netcdf_diag_
endif
-! Load data array for current satellite
- read(lunin) data_s,luse,ioid
-
- if (nobskeep>0) then
-! write(6,*)'setuprad: nobskeep',nobskeep
- call stop2(275)
- end if
-
! PROCESSING OF SATELLITE DATA
! Loop over data in this block
@@ -800,6 +841,11 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
zsges=data_s(izz,n)
nadir = nint(data_s(iscan_pos,n))
pangs = data_s(iszen_ang,n)
+ if (iasi) then
+ cloud_frac = data_s(21,n)
+ else
+ cloud_frac = r_missing
+ end if
! Extract warm load temperatures
! wltm1 = data_s(isty,n)
! wltm2 = data_s(istp,n)
@@ -815,7 +861,7 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
if(seviri .and. abs(data_s(iszen_ang,n)) > 180.0_r_kind) data_s(iszen_ang,n)=r100
-! Set land/sea, snow, ice percentages and flags (no time interpolation)
+! Set land/sea, snow, i e percentages and flags (no time interpolation)
sea = data_s(ifrac_sea,n) >= 0.99_r_kind
land = data_s(ifrac_lnd,n) >= 0.99_r_kind
@@ -847,25 +893,6 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
iinstr=getindex(idnames,trim(covtype))
endif
endif
- do jc=1,nchanl
- j=ich(jc)
-
- tnoise(jc)=varch(j)
-
- if(sea .and. (varch_sea(j)>zero)) tnoise(jc)=varch_sea(j)
- if(land .and. (varch_land(j)>zero)) tnoise(jc)=varch_land(j)
- if(ice .and. (varch_ice(j)>zero)) tnoise(jc)=varch_ice(j)
- if(snow .and. (varch_snow(j)>zero)) tnoise(jc)=varch_snow(j)
- if(mixed .and. (varch_mixed(j)>zero)) tnoise(jc)=varch_mixed(j)
- tnoise_save = tnoise(jc)
-
- channel_passive=iuse_rad(j)==-1 .or. iuse_rad(j)==0
- if (iuse_rad(j)< -1 .or. (channel_passive .and. &
- .not.rad_diagsave)) tnoise(jc)=r1e10
- if (passive_bc .and. channel_passive) tnoise(jc)=tnoise_save
- if (tnoise(jc) < 1.e4_r_kind) toss = .false.
- end do
-
! Count data of different surface types
if(luse(n))then
if (mixed) then
@@ -886,9 +913,30 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
endif
endif
+ do jc=1,nchanl
+ j=ich(jc)
+
+ tnoise(jc)=varch(j)
+
+ if(mixed .and. (varch_mixed(j)>zero)) then
+ tnoise(jc)=varch_mixed(j)
+ else if(snow .and. (varch_snow(j)>zero)) then
+ tnoise(jc)=varch_snow(j)
+ else if(ice .and. (varch_ice(j)>zero)) then
+ tnoise(jc)=varch_ice(j)
+ else if(land .and. (varch_land(j)>zero)) then
+ tnoise(jc)=varch_land(j)
+ else if(sea .and. (varch_sea(j)>zero)) then
+ tnoise(jc)=varch_sea(j)
+ end if
+
+ if (.not. (passive_bc .and. channel_passive(j))) then
+ if (iuse_rad(j)< -1 .or. (channel_passive(j) .and. &
+ .not.rad_diagsave)) tnoise(jc)=r1e10
+ end if
+
! Load channel data into work array.
- do i = 1,nchanl
- tb_obs(i) = data_s(i+nreal,n)
+ tb_obs(jc) = data_s(jc+nreal,n)
end do
@@ -901,7 +949,7 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
call call_crtm(obstype,dtime,data_s(:,n),nchanl,nreal,ich, &
tvp,qvp,qs,clw_guess,ciw_guess,rain_guess,snow_guess,prsltmp,prsitmp, &
trop5,tzbgr,dtsavg,sfc_speed, &
- tsim,emissivity,ptau5,ts,emissivity_k, &
+ tsim,emissivity,chan_level,ptau5,ts,emissivity_k, &
temp,wmix,jacobian,error_status,tsim_clr=tsim_clr,tcc=tcc, &
tcwv=tcwv,hwp_ratio=hwp_ratio,stability=stability)
if(gmi) then
@@ -912,7 +960,7 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
call call_crtm(obstype,dtime,data_s(:,n),nchanl,nreal,ich, &
tvp,qvp,qs,clw_guess,ciw_guess,rain_guess,snow_guess,prsltmp,prsitmp, &
trop5,tzbgr,dtsavg,sfc_speed, &
- tsim2,emissivity2,ptau52,ts2,emissivity_k2, &
+ tsim2,emissivity2,chan_level,ptau52,ts2,emissivity_k2, &
temp2,wmix2,jacobian2,error_status,tsim_clr=tsim_clr2,tcc=tcc,&
tcwv=tcwv,hwp_ratio=hwp_ratio,stability=stability)
! merge
@@ -936,7 +984,7 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
call call_crtm(obstype,dtime,data_s(:,n),nchanl,nreal,ich, &
tvp,qvp,qs,clw_guess,ciw_guess,rain_guess,snow_guess,prsltmp,prsitmp, &
trop5,tzbgr,dtsavg,sfc_speed, &
- tsim,emissivity,ptau5,ts,emissivity_k, &
+ tsim,emissivity,chan_level,ptau5,ts,emissivity_k, &
temp,wmix,jacobian,error_status)
if(gmi) then
gmi_low_angles(1:3)=data_s(ilzen_ang:iscan_ang,n)
@@ -946,7 +994,7 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
call call_crtm(obstype,dtime,data_s(:,n),nchanl,nreal,ich, &
tvp,qvp,qs,clw_guess,ciw_guess,rain_guess,snow_guess,prsltmp,prsitmp, &
trop5,tzbgr,dtsavg,sfc_speed, &
- tsim2,emissivity2,ptau52,ts2,emissivity_k2, &
+ tsim2,emissivity2,chan_level,ptau52,ts2,emissivity_k2, &
temp2,wmix2,jacobian2,error_status)
! merge
emissivity(10:13) = emissivity2(10:13)
@@ -996,10 +1044,11 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
tsavg5=tsavg5+dtsavg
endif
+! Compute microwave cloud liquid water or graupel water path for bias correction and QC.
+ if (adp_anglebc) then
! If using adaptive angle dependent bias correction, update the predicctors
! for this part of bias correction. The AMSUA cloud liquid water algorithm
! uses total angle dependent bias correction for channels 1 and 2
- if (adp_anglebc) then
do i=1,nchanl
mm=ich(i)
if (goessndr .or. goes_img .or. ahi .or. seviri .or. ssmi .or. ssmis .or. gmi .or. abi) then
@@ -1018,8 +1067,7 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
end if
end do
end if
-
-! Compute microwave cloud liquid water or graupel water path for bias correction and QC.
+!*****
clw_obs=zero
clw_guess_retrieval=zero
gwp=zero
@@ -1056,10 +1104,8 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
id_qc(1:nchanl) = ifail_cloud_qc
endif
endif
- endif
! Screening for cold-air outbreak area (only applied to MW for now)
- if (cao_check .and. radmod%lprecip) then
- if(microwave .and. sea) then
+ if (cao_check .and. radmod%lprecip) then
if(radmod%lcloud_fwd) then
cao_flag = (stability < 12.0_r_kind) .and. (hwp_ratio < half) .and. (tcwv < 8.0_r_kind)
if (cao_flag) then ! remove all tropospheric channels
@@ -1082,12 +1128,14 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
endif
endif
+! totbc = total bias correction !emily
+ totbc=zero !emily
predbias=zero
- cld_rbc_idx2=zero
+
+!$omp parallel do schedule(dynamic,1) private(i,mm,j,k,tlap,node,bias)
do i=1,nchanl
mm=ich(i)
-
!*****
! COMPUTE AND APPLY BIAS CORRECTION TO SIMULATED VALUES
!*****
@@ -1113,30 +1161,10 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
else
pred(3,i) = clw_obs*cosza*cosza
end if
+
if(radmod%lcloud_fwd .and. sea) pred(3,i ) = zero
-
-
-
! Apply bias correction
-
- kmax(i) = 0
- if (lwrite_peakwt .or. passive_bc) then
- ptau5derivmax = -9.9e31_r_kind
-! maximum of weighting function is level at which transmittance
-! (ptau5) is changing the fastest. This is used for the level
-! assignment (needed for vertical localization).
- weightmax(i) = zero
- do k=2,nsig
- ptau5deriv = abs( (ptau5(k-1,i)-ptau5(k,i))/ &
- (log(prsltmp(k-1))-log(prsltmp(k))) )
- if (ptau5deriv > ptau5derivmax) then
- ptau5derivmax = ptau5deriv
- kmax(i) = k
- weightmax(i) = r10*prsitmp(k) ! cb to mb.
- end if
- enddo
- end if
tlapchn(i)= (ptau5(2,i)-ptau5(1,i))*(tsavg5-tvp(2))
do k=2,nsig-1
@@ -1182,22 +1210,6 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
end do
end if
- if (abi2km .and. regional) then
- abi2km_bc = zero
- abi2km_bc(2) = 233.5_r_kind
- abi2km_bc(3) = 241.7_r_kind
- abi2km_bc(4) = 250.5_r_kind
- pred(:,i) = zero
- if (i>=2 .and. i<=4) then
- if (tb_obs(i) > 190.0_r_kind .and. tb_obs(i) < 300.0_r_kind) then
- pred(1,i)=1.0_r_kind
- pred(2,i)=tb_obs(i)-abi2km_bc(i)
- pred(3,i)=(tb_obs(i)-abi2km_bc(i))**2
- pred(4,i)=(tb_obs(i)-abi2km_bc(i))**3
- end if
- end if
- end if
-
do j = 1,npred
predbias(j,i) = predchan(j,i)*pred(j,i)
end do
@@ -1214,12 +1226,14 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
! tbcnob = obs - guess before bias correction
tbcnob(i) = tb_obs(i) - tsim(i)
tbc(i) = tbcnob(i)
-
+
do j=1, npred-angord
tbc(i)=tbc(i) - predbias(j,i) !obs-ges with bias correction
+ totbc(i) = totbc(i) + predbias(j,i)
end do
tbc(i)=tbc(i) - predbias(npred+1,i)
tbc(i)=tbc(i) - predbias(npred+2,i)
+ totbc(i) = totbc(i) + predbias(npred+1,i)+predbias(npred+2,i)
! Calculate cloud effect for QC
if (radmod%cld_effect .and. eff_area) then
@@ -1234,15 +1248,37 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
bias = bias+predbias(npred+2,i)
cldeff_obs(i)=cldeff_obs(i) - bias ! observed cloud delta (bias corrected)
endif
+ end do
+ kmax = 0
+ if (lwrite_peakwt .or. passive_bc) then
+!$omp parallel do schedule(dynamic,1) private(i,k,ptau5derivmax,ptau5deriv)
+ do i=1,nchanl
+ ptau5derivmax = -9.9e31_r_kind
+! maximum of weighting function is level at which transmittance
+! (ptau5) is changing the fastest. This is used for the level
+! assignment (needed for vertical localization).
+ weightmax(i) = zero
+ do k=2,nsig
+ ptau5deriv = abs( (ptau5(k-1,i)-ptau5(k,i))/ &
+ (log(prsltmp(k-1))-log(prsltmp(k))) )
+ if (ptau5deriv > ptau5derivmax) then
+ ptau5derivmax = ptau5deriv
+ kmax(i) = k
+ weightmax(i) = r10*prsitmp(k) ! cb to mb.
+ end if
+ enddo
! End of loop over channels
- end do
+ end do
+ end if
! Compute retrieved microwave cloud liquid water and
! assign cld_rbc_idx for bias correction in allsky conditions
cld_rbc_idx=one
+ cld_rbc_idx2=zero
if (radmod%lcloud_fwd .and. radmod%ex_biascor .and. eff_area) then
ierrret=0
+!$omp parallel do schedule(dynamic,1) private(i,mm,j)
do i=1,nchanl
mm=ich(i)
tsim_bc(i)=tsim(i)
@@ -1258,19 +1294,19 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
tsim_clr_bc(i)=tsim_clr_bc(i)+predbias(npred+2,i)
end do
- if(amsua.or.atms) call ret_amsua(tsim_bc,nchanl,tsavg5,zasat,clw_guess_retrieval,ierrret)
- if(gmi) then
- call gmi_37pol_diff(tsim_bc(6),tsim_bc(7),tsim_clr_bc(6),tsim_clr_bc(7),clw_guess_retrieval,ierrret)
- call gmi_37pol_diff(tb_obs(6),tb_obs(7),tsim_clr_bc(6),tsim_clr_bc(7),clw_obs,ierrret)
+ if(amsua.or.atms) then
+ call ret_amsua(tsim_bc,nchanl,tsavg5,zasat,clw_guess_retrieval,ierrret)
+ else if(gmi) then
+ call gmi_37pol_diff(tsim(6),tsim(7),tsim_clr(6),tsim_clr(7),clw_guess_retrieval,ierrret)
+ call gmi_37pol_diff(tb_obs(6),tb_obs(7),tsim_clr(6),tsim_clr(7),clw_obs,ierrret)
end if
if (radmod%ex_obserr=='ex_obserr1') then
call radiance_ex_biascor(radmod,nchanl,tsim_bc,tsavg5,zasat, &
clw_guess_retrieval,clw_obs,cld_rbc_idx,ierrret)
- end if
-! if (radmod%ex_obserr=='ex_obserr2') then ! comment out for now, need to be tested
+! else if (radmod%ex_obserr=='ex_obserr2') then ! comment out for now, need to be tested
! call radiance_ex_biascor(radmod,nchanl,cldeff_obs,cldeff_fg,cld_rbc_idx)
! end if
- if (radmod%ex_obserr=='ex_obserr3') then
+ else if (radmod%ex_obserr=='ex_obserr3') then
call radiance_ex_biascor_gmi(radmod,clw_obs,clw_guess_retrieval,nchanl,cld_rbc_idx)
end if
@@ -1296,11 +1332,12 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
do i=1,nchanl
pred(6,i) = zero
pred(7,i) = zero
- clw_avg = half*(clw_obs+clw_guess_retrieval)
+! Need to investigate clw_ave = half*(clw_obs+clw_guess_retrieval)
+ clw_avg = zero
if (i > 3 .and. clw_obs > 0.05_r_kind .and. clw_guess_retrieval > 0.05_r_kind .and. &
- abs(clw_obs-clw_guess_retrieval) < 0.005_r_kind .and. clw_avg < 0.5_r_kind) cld_rbc_idx2(i) = one
+ abs(clw_obs-clw_guess_retrieval) < 0.005_r_kind .and. clw_avg < 0.5_r_kind) cld_rbc_idx2(i) = zero
if (i < 5 .and. clw_obs > 0.2_r_kind .and. clw_guess_retrieval > 0.2_r_kind .and. &
- abs(clw_obs-clw_guess_retrieval) < 0.005_r_kind .and. clw_avg < 0.5_r_kind) cld_rbc_idx2(i) = one
+ abs(clw_obs-clw_guess_retrieval) < 0.005_r_kind .and. clw_avg < 0.5_r_kind) cld_rbc_idx2(i) = zero
if( i > 3 .and. clw_obs > 0.05_r_kind .and. clw_guess_retrieval > 0.05_r_kind .and. cld_rbc_idx(i) == zero) then
pred(6,i) = clw_avg*clw_avg
@@ -1323,17 +1360,17 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
! Assign observation error for all-sky radiances
if (radmod%lcloud_fwd .and. eff_area) then
- if (radmod%ex_obserr=='ex_obserr1') &
+ if (radmod%ex_obserr=='ex_obserr1') then
call radiance_ex_obserr(radmod,nchanl,clw_obs,clw_guess_retrieval,tnoise,tnoise_cld,error0)
- if (radmod%ex_obserr=='ex_obserr3') &
+ else if (radmod%ex_obserr=='ex_obserr3') then
call radiance_ex_obserr_gmi(radmod,nchanl,clw_obs,clw_guess_retrieval,tnoise,tnoise_cld,error0)
+ end if
end if
do i=1,nchanl
mm=ich(i)
- channel_passive=iuse_rad(ich(i))==-1 .or. iuse_rad(ich(i))==0
- if(tnoise(i) < 1.e4_r_kind .or. (channel_passive .and. rad_diagsave) &
- .or. (passive_bc .and. channel_passive))then
+ if(tnoise(i) < 1.e4_r_kind .or. (channel_passive(mm) .and. rad_diagsave) &
+ .or. (passive_bc .and. channel_passive(mm)))then
varinv(i) = varinv(i)/error0(i)**2
errf(i) = error0(i)
else
@@ -1365,20 +1402,18 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
do i=1,nchanl
m=ich(i)
- if (varinv(i) < tiny_r_kind) then
- varinv_use(i) = zero
+ if (icld_det(m)>0 .and. varinv(i) >= tiny_r_kind) then
+ varinv_use(i) = varinv(i)
else
- if ((icld_det(m)>0)) then
- varinv_use(i) = varinv(i)
- else
- varinv_use(i) = zero
- end if
+ varinv_use(i) = zero
end if
end do
- call qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse(n),goessndr, &
- cris,hirs,zsges,cenlat,frac_sea,pangs,trop5,zasat,tzbgr,tsavg5,tbc,tb_obs,tbcnob,tnoise, &
- wavenumber,ptau5,prsltmp,tvp,temp,wmix,emissivity_k,ts, &
- id_qc,aivals,errf,varinv,varinv_use,cld,cldp,kmax,zero_irjaco3_pole(n))
+
+ call qc_irsnd(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse(n),goessndr,airs,cris,iasi, &
+ hirs,zsges,cenlat,frac_sea,pangs,trop5,zasat,tzbgr,tsavg5,tbc,tb_obs,tbcnob,tnoise, &
+ wavenumber,ptau5,prsltmp,tvp,temp,wmix,chan_level,emissivity_k,ts,tsim, &
+ id_qc,aivals,errf,varinv,varinv_use,cld,cldp,kmax,zero_irjaco3_pole(n), &
+ imager_cluster_fraction(:,n), imager_cluster_bt(:,:,n), imager_chan_stdev(:,n),imager_model_bt(:,n))
! --------- MSU -------------------
! QC MSU data
@@ -1399,7 +1434,8 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
call qc_amsua(nchanl,is,ndat,nsig,npred,sea,land,ice,snow,mixed,luse(n), &
zsges,cenlat,tb_obsbc1,cosza,clw_obs,tbc,ptau5,emissivity_k,ts, &
- pred,predchan,id_qc,aivals,errf,errf0,clw_obs,varinv,cldeff_obs,cldeff_fg,factch6, &
+ pred,predchan,id_qc,aivals,errf,errf0,clw_obs,varinv,varinv_sdoei,varinv_grosschk,varinv_after_jsfcchk,varinv_after_sdoei,cldeff_obs,cldeff_fg,factch6,factch4,qc4emiss_out, & !emily
+ ! pred,predchan,id_qc,aivals,errf,errf0,clw_obs,varinv,cldeff_obs,cldeff_fg,factch6, & !orig
cld_rbc_idx,sfc_speed,error0,clw_guess_retrieval,scatp,radmod)
! If cloud impacted channels not used turn off predictor
@@ -1440,7 +1476,8 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
call qc_atms(nchanl,is,ndat,nsig,npred,sea,land,ice,snow,mixed,luse(n), &
zsges,cenlat,tb_obsbc1,cosza,clw_obs,tbc,ptau5,emissivity_k,ts, &
- pred,predchan,id_qc,aivals,errf,errf0,clw_obs,varinv,cldeff_obs,cldeff_fg,factch6, &
+ pred,predchan,id_qc,aivals,errf,errf0,clw_obs,varinv,varinv_sdoei,varinv_grosschk,varinv_after_jsfcchk,varinv_after_sdoei,cldeff_obs,cldeff_fg,factch6,factch4,qc4emiss_out, & ! emily
+ ! pred,predchan,id_qc,aivals,errf,errf0,clw_obs,varinv,cldeff_obs,cldeff_fg,factch6, & !orig
cld_rbc_idx,sfc_speed,error0,clw_guess_retrieval,scatp,radmod)
! ---------- GOES imager --------------
@@ -1464,14 +1501,10 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
else if (seviri .or. abi .or. ahi) then
do i=1,nchanl
m=ich(i)
- if (varinv(i) < tiny_r_kind) then
- varinv_use(i) = zero
+ if (icld_det(m)>0 .and. varinv(i) >= tiny_r_kind) then
+ varinv_use(i) = varinv(i)
else
- if ((icld_det(m)>0)) then
- varinv_use(i) = varinv(i)
- else
- varinv_use(i) = zero
- end if
+ varinv_use(i) = zero
end if
end do
@@ -1481,7 +1514,21 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
call qc_geocsr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse(n), &
zsges,trop5,tzbgr,tsavg5,tb_obs_sdv,tbc,tb_obs,tnoise,ptau5,prsltmp,tvp,temp,wmix,emissivity_k,ts, &
- id_qc,aivals,errf,varinv,varinv_use,cld,cldp,kmax,abi,ahi,seviri)
+! id_qc,aivals,errf,varinv,varinv_use,cld,cldp,kmax,abi,ahi,seviri)
+!>>emily
+ id_qc,aivals,errf,varinv,varinv_use, &
+ varinv_after_sfcterrianchk, &
+ varinv_after_rangechk, &
+ varinv_after_topo, &
+ varinv_after_transmittop, &
+ varinv_after_clddet, &
+ varinv_after_stdchk, &
+ varinv_after_grossroutinechk, &
+ varinv_after_stdadj, &
+ varinv_after_nsstret, &
+ varinv_after_jsfcchk, &
+!<>emily
+ do i=1,nchanl
+ varinv_after_clrfracchk(i) = varinv(i)
+ end do
+!< tiny_r_kind .and. &
- (tb_obs(7)-tb_obs(8))-(tsim(7)-tsim(8)) <= -0.75_r_kind) then
- varinv(i)=zero
- varinv_use(i)=zero
- end if
- end if
- end do
+ if(abi .or. ahi) then
+ do i = 1,nchanl
+ if( i/=2 .and. i/=3 .and.varinv(i) > tiny_r_kind) then
+ if((tb_obs(7)-tb_obs(8))-(tsim(7)-tsim(8)) <= -0.75_r_kind) then
+ varinv(i)=zero
+ end if
+ end if
+ end do
+ end if
!
! ---------- AVRHRR --------------
@@ -1526,20 +1580,18 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
! channels with iuse_rad=-1 or 0 are used in cloud detection.
do i=1,nchanl
m=ich(i)
- if (varinv(i) < tiny_r_kind) then
- varinv_use(i) = zero
+ if (icld_det(m)>0 .and. varinv(i) >= tiny_r_kind) then
+ varinv_use(i) = varinv(i)
else
- if ((icld_det(m)>0)) then
- varinv_use(i) = varinv(i)
- else
- varinv_use(i) = zero
- end if
+ varinv_use(i) = zero
end if
end do
call qc_avhrr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse(n), &
zsges,cenlat,frac_sea,pangs,trop5,tzbgr,tsavg5,tbc,tb_obs,tnoise, &
wavenumber,ptau5,prsltmp,tvp,temp,wmix,emissivity_k,ts, &
+ varinv_after_wavenum,varinv_after_rangechk,varinv_after_topo,varinv_after_transmittop, & !emily
+ varinv_after_clddet, varinv_after_nsstret, varinv_after_jsfcchk, & !emily
id_qc,aivals,errf,varinv,varinv_use,cld,cldp)
else if (viirs) then
@@ -1549,20 +1601,18 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
! NOTE: use qc_avhrr for viirs qc
do i=1,nchanl
m=ich(i)
- if (varinv(i) < tiny_r_kind) then
- varinv_use(i) = zero
+ if (icld_det(m)>0 .and. varinv(i) >= tiny_r_kind) then
+ varinv_use(i) = varinv(i)
else
- if ((icld_det(m)>0)) then
- varinv_use(i) = varinv(i)
- else
- varinv_use(i) = zero
- end if
+ varinv_use(i) = zero
end if
end do
call qc_avhrr(nchanl,is,ndat,nsig,ich,sea,land,ice,snow,luse(n), &
zsges,cenlat,frac_sea,pangs,trop5,tzbgr,tsavg5,tbc,tb_obs,tnoise, &
wavenumber,ptau5,prsltmp,tvp,temp,wmix,emissivity_k,ts, &
+ varinv_after_wavenum,varinv_after_rangechk,varinv_after_topo,varinv_after_transmittop, & !emily
+ varinv_after_clddet, varinv_after_nsstret, varinv_after_jsfcchk, & !emily
id_qc,aivals,errf,varinv,varinv_use,cld,cldp)
! ---------- SSM/I , SSMIS, AMSRE -------------------
@@ -1570,7 +1620,6 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
else if( ssmi .or. amsre .or. ssmis )then
- frac_sea=data_s(ifrac_sea,n)
if(amsre)then
bearaz= (270._r_kind-data_s(ilazi_ang,n))*deg2rad
sun_zenith=data_s(iszen_ang,n)*deg2rad
@@ -1583,6 +1632,15 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
zsges,luse(n),sea,mixed, &
temp,wmix,ts,emissivity_k,ierrret,kraintype,tpwc_obs,clw_obs,sgagl,tzbgr, &
tbc,tbcnob,tsim,tnoise,ssmi,amsre_low,amsre_mid,amsre_hig,ssmis, &
+ varinv_after_grossroutinechk_over_ocean, & !emily
+ varinv_after_topo, & !emily
+ varinv_after_sfcchk, & !emily
+ varinv_after_ch2chk, & !emily
+ varinv_after_grossroutinechk,& !emily
+ varinv_after_scatteringchk, & !emily
+ varinv_after_nsstret, & !emily
+ varinv_after_jsfcchk, & !emily
+ pred9,pred10,pred11, & !emily
varinv,errf,aivals(1,is),id_qc)
! ---------- AMSR2 -------------------
@@ -1672,23 +1730,33 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
if(luse(n))aivals(7,is) = aivals(7,is) + one
end if
end if
+ varinv_after_grosschk(i) = varinv(i) !emily
end do
if(amsua .or. atms .or. amsub .or. mhs .or. msu .or. hsb)then
- if(amsua)nlev=6
- if(atms)nlev=7
- if(amsub .or. mhs)nlev=5
- if(hsb)nlev=4
- if(msu)nlev=4
+ if(amsua)then
+ nlev=6
+ else if(atms)then
+ nlev=7
+ else if(amsub .or. mhs)then
+ nlev=5
+ else if(hsb)then
+ nlev=4
+ else if(msu)then
+ nlev=4
+ end if
kval=0
do i=2,nlev
! do i=1,nlev
- channel_passive=iuse_rad(ich(i))==-1 .or. iuse_rad(ich(i))==0
- if (varinv(i)=1) .or. &
- (passive_bc .and. channel_passive))) then
+ mm=ich(i)
+ if (varinv(i)=1) .or. &
+ (passive_bc .and. channel_passive(mm)))) then
kval=max(i-1,kval)
- if(amsub .or. hsb .or. mhs)kval=nlev
- if((amsua .or. atms) .and. i <= 3)kval = zero
+ if(amsub .or. hsb .or. mhs)then
+ kval=nlev
+ else if((amsua .or. atms) .and. i <= 3) then
+ kval = zero
+ end if
end if
end do
if(kval > 0)then
@@ -1699,60 +1767,55 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
if(amsua)then
varinv(15)=zero
if(id_qc(15) == igood_qc)id_qc(15)=ifail_interchan_qc
- end if
- if (atms) then
+ else if (atms) then
varinv(16:18)=zero
if(id_qc(16) == igood_qc)id_qc(16)=ifail_interchan_qc
if(id_qc(17) == igood_qc)id_qc(17)=ifail_interchan_qc
if(id_qc(18) == igood_qc)id_qc(18)=ifail_interchan_qc
end if
end if
- end if
-
- if(mhs.or.amsub)then
- do i = 1, nchanl
- m = ich(i)
- if(sea .and. isst_det(m) >0 .and. tsavg5 < 278.0_r_kind) then
- varinv(i) = zero
- if(id_qc(i) == igood_qc)id_qc(i)=ifail_isst_det
- endif
- if(sea .and. iwndspeed_det(m)>0 .and. tsavg5 < 285.0_r_kind .and. sfc_speed > 10.0_r_kind) then
- varinv(i) = zero
- if(id_qc(i) == igood_qc)id_qc(i)=ifail_iwndspeed_det
- endif
- if(iomg_det(m) > 0 .and. abs(tbcnob(2)) > 5.0_r_kind) then
- varinv(i) = zero
- if(id_qc(i) == igood_qc)id_qc(i)=ifail_iomg_det
- endif
-
- if(itopo_det(m) > 0 .and. zsges > 1000.0_r_kind ) then
- varinv(i) = zero
- if(id_qc(i) == igood_qc)id_qc(i)=ifail_itopo_det
- endif
- enddo
+ if(mhs.or.amsub)then
+ do i = 1, nchanl
+ m = ich(i)
+ if(sea)then
+ if(isst_det(m) >0 .and. tsavg5 < 278.0_r_kind) then
+ varinv(i) = zero
+ if(id_qc(i) == igood_qc)id_qc(i)=ifail_isst_det
+
+ else if(iwndspeed_det(m)>0 .and. tsavg5 < 285.0_r_kind .and. sfc_speed > 10.0_r_kind) then
+ varinv(i) = zero
+ if(id_qc(i) == igood_qc)id_qc(i)=ifail_iwndspeed_det
+ endif
+ end if
+ if(iomg_det(m) > 0 .and. abs(tbcnob(2)) > 5.0_r_kind) then
+ varinv(i) = zero
+ if(id_qc(i) == igood_qc)id_qc(i)=ifail_iomg_det
+
+ else if(itopo_det(m) > 0 .and. zsges > 1000.0_r_kind ) then
+ varinv(i) = zero
+ if(id_qc(i) == igood_qc)id_qc(i)=ifail_itopo_det
+ endif
+ enddo
+ endif
endif
! Screen out land surface types by channel. Flags are set in satinfo file.
do i = 1, nchanl
m = ich(i)
- if(iwater_det(m) > 0 .and. sea) then
+ if(sea .and. iwater_det(m) > 0) then
varinv(i) = zero
if(id_qc(i) == igood_qc)id_qc(i)=ifail_iwater_det
- endif
- if(isnow_det(m) > 0 .and. snow) then
+ else if(snow .and. isnow_det(m) > 0 ) then
varinv(i) = zero
if(id_qc(i) == igood_qc)id_qc(i)=ifail_isnow_det
- endif
- if(mixed .and. imix_det(m) > 0) then
+ else if(mixed .and. imix_det(m) > 0) then
varinv(i) = zero
if(id_qc(i) == igood_qc)id_qc(i)=ifail_imix_det
- endif
- if(land .and. iland_det(m) > 0) then
+ else if(land .and. iland_det(m) > 0) then
varinv(i) = zero
if(id_qc(i) == igood_qc)id_qc(i)=ifail_iland_det
- endif
- if(ice .and. iice_det(m) > 0) then
+ else if(ice .and. iice_det(m) > 0) then
varinv(i) = zero
if(id_qc(i) == igood_qc)id_qc(i)=ifail_iice_det
endif
@@ -1767,39 +1830,37 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
endif
endif
- do i = 1,nchanl
-
! Reject radiances for single radiance test
- if (lsingleradob) then
+ if (lsingleradob) then
+ do i = 1,nchanl
+
! if the channels are beyond 0.01 of oblat/oblon, specified
! in gsi namelist, or aren't of type 'oneob_type', reject
if ( (abs(cenlat - oblat) > one/r100 .or. &
abs(cenlon - oblon) > one/r100) .or. &
obstype /= oneob_type ) then
varinv(i) = zero
- varinv_use(i) = zero
if (id_qc(i) == igood_qc) id_qc(i) = ifail_outside_range
else
! if obchan <= zero, keep all footprints, if obchan > zero,
! keep only that which has channel obchan
if (i /= obchan .and. obchan > zero) then
varinv(i) = zero
- varinv_use(i) = zero
if (id_qc(i) == igood_qc) id_qc(i) = ifail_outside_range
endif
endif !cenlat/lon
- endif !lsingleradob
- enddo
+ enddo
+ endif !lsingleradob
diagadd=zero
account_for_corr_obs = .false.
- iii=0
varinv0=zero
+ raterr2 = zero
+!$omp parallel do schedule(dynamic,1) private(ii,m,k,asum)
do ii=1,nchanl
m=ich(ii)
if (varinv(ii)>tiny_r_kind .and. iuse_rad(m)>=1) then
- iii=iii+1
varinv0(ii)=varinv(ii)
raterr2(ii)=error0(ii)**2*varinv0(ii)
if (l_may_be_passive .and. .not. retrieval) then
@@ -1813,10 +1874,18 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
end if
end if
enddo
+ iii=0
+ do ii=1,nchanl
+ m=ich(ii)
+ if (varinv(ii)>tiny_r_kind .and. iuse_rad(m)>=1) then
+ iii=iii+1
+ end if
+ end do
err2 = one/error0**2
tbc0=tbc
tb_obs0=tb_obs
- wgtjo=varinv0
+! wgtjo=varinv0 !orig
+ wgtjo=varinv !emily
if (l_may_be_passive .and. .not. retrieval) then
if(iii>0 .and. iinstr.ne.-1)then
chan_count=(iii*(iii+1))/2
@@ -1843,18 +1912,14 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
m = ich(i)
if(luse(n))then
- drad = tbc0(i)
- dradnob = tbcnob(i)
+ drad = tbc0(i)*cld_rbc_idx(i)
+ dradnob = tbcnob(i)*cld_rbc_idx(i)
varrad = tbc(i)*varinv(i)
stats(1,m) = stats(1,m) + one !number of obs
-! stats(3,m) = stats(3,m) + drad !obs-mod(w_biascor)
-! stats(4,m) = stats(4,m) + tbc0(i)*drad !(obs-mod(w_biascor))**2
-! stats(5,m) = stats(5,m) + tbc(i)*varrad !penalty contribution
-! stats(6,m) = stats(6,m) + dradnob !obs-mod(w/o_biascor)
- stats(3,m) = stats(3,m) + drad*cld_rbc_idx(i) !obs-mod(w_biascor)
- stats(4,m) = stats(4,m) + tbc0(i)*drad*cld_rbc_idx(i)!(obs-mod(w_biascor))**2
+ stats(3,m) = stats(3,m) + drad !obs-mod(w_biascor)
+ stats(4,m) = stats(4,m) + tbc0(i)*drad !(obs-mod(w_biascor))**2
stats(5,m) = stats(5,m) + tbc(i)*varrad !penalty contribution
- stats(6,m) = stats(6,m) + dradnob*cld_rbc_idx(i) !obs-mod(w/o_biascor)
+ stats(6,m) = stats(6,m) + dradnob !obs-mod(w/o_biascor)
if (account_for_corr_obs .and. (cor_opt ==1 .or. cor_opt ==2) ) then
exp_arg = -half*tbc(i)**2
@@ -1888,7 +1953,7 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
! summation of observation number
if (newpc4pred) then
- ostats(m) = ostats(m) + one*cld_rbc_idx(i)
+ ostats(m) = ostats(m) + cld_rbc_idx(i)
end if
end if
@@ -1899,12 +1964,11 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
! At the end of analysis, prepare for bias correction for monitored channels
! Only "good monitoring" obs are included in J_passive calculation.
- channel_passive=iuse_rad(m)==-1 .or. iuse_rad(m)==0
- if (passive_bc .and. (jiter>miter) .and. channel_passive) then
+ if (passive_bc .and. (jiter>miter) .and. channel_passive(m)) then
! summation of observation number,
! skip ostats accumulation for channels without coef. initialization
if (newpc4pred .and. luse(n) .and. any(predx(:,m)/=zero)) then
- ostats(m) = ostats(m) + one*cld_rbc_idx(i)
+ ostats(m) = ostats(m) + cld_rbc_idx(i)
end if
iccm=iccm+1
end if
@@ -1950,7 +2014,7 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
my_head%raterr2(icc),my_head%pred(npred,icc), &
my_head%dtb_dvar(nsigradjac,icc), &
my_head%ich(icc),&
- my_head%icx(icc))
+ my_head%icx(icc),my_head%iccerr(icc))
if(luse_obsdiag)allocate(my_head%diags(icc))
call get_ij(mm1,slats,slons,my_head%ij,my_head%wij)
@@ -2018,6 +2082,13 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
end if ! end of newpc4pred loop
end if
end do
+ ncr=0
+ do ii=1,iii
+ my_head%iccerr(ii) = ncr
+ do mm=1,ii
+ ncr=ncr+1
+ end do
+ end do
my_head%nchan = iii ! profile observation count
my_head%use_corr_obs=.false.
@@ -2112,23 +2183,28 @@ subroutine setuprad(obsLL,odiagLL,lunin,mype,aivals,stats,nchanl,nreal,nobs,&
allocate(my_headm%res(iccm),my_headm%err2(iccm), &
my_headm%raterr2(iccm),my_headm%pred(npred,iccm), &
my_headm%ich(iccm), &
- my_headm%icx(iccm))
+ my_headm%icx(iccm),my_headm%iccerr(iccm))
my_headm%nchan = iccm ! profile observation count
my_headm%time=dtime
my_headm%luse=luse(n)
my_headm%ich(:)=-1
iii=0
+ ncr=0
do ii=1,nchanl
m=ich(ii)
- channel_passive=iuse_rad(m)==-1 .or. iuse_rad(m)==0
- if (varinv(ii)>tiny_r_kind .and. channel_passive) then
+ if (varinv(ii)>tiny_r_kind .and. channel_passive(m)) then
iii=iii+1
my_headm%res(iii)=tbc(ii) ! obs-ges innovation
my_headm%err2(iii)=one/error0(ii)**2 ! 1/(obs error)**2 (original uninflated error)
my_headm%raterr2(iii)=error0(ii)**2*varinv(ii) ! (original error)/(inflated error)
my_headm%icx(iii)=m ! channel index
+ do mm=1,ii
+ ncr=ncr+1
+ end do
+
+ my_headm%iccerr(iii)=ncr ! channel index
do k=1,npred
my_headm%pred(k,iii)=pred(k,ii)*upd_pred(k)*max(cld_rbc_idx(ii),cld_rbc_idx2(ii))
end do
@@ -2562,6 +2638,8 @@ subroutine contents_netcdf_diag_(odiags,idv,iob)
real(r_single),parameter:: missing = -9.99e9_r_single
integer(i_kind),parameter:: imissing = -999999
real(r_kind),dimension(:),allocatable :: predbias_angord
+ character(128) :: fieldname
+ integer(i_kind) :: iabsorb, icloud
if (adp_anglebc) then
allocate(predbias_angord(angord) )
@@ -2571,41 +2649,42 @@ subroutine contents_netcdf_diag_(odiags,idv,iob)
do i=1,nchanl_diag
call nc_diag_metadata("Channel_Index", i )
call nc_diag_metadata("Observation_Class", obsclass )
- call nc_diag_metadata("Latitude", sngl(cenlat) ) ! observation latitude (degrees)
- call nc_diag_metadata("Longitude", sngl(cenlon) ) ! observation longitude (degrees)
+ call nc_diag_metadata_to_single("Latitude",cenlat ) ! observation latitude (degrees)
+ call nc_diag_metadata_to_single("Longitude",cenlon ) ! observation longitude (degrees)
- call nc_diag_metadata("Elevation", sngl(zsges) ) ! model (guess) elevation at observation location
+ call nc_diag_metadata_to_single("Elevation",zsges ) ! model (guess) elevation at observation location
- call nc_diag_metadata("Obs_Time", sngl(dtime-time_offset) ) ! observation time (hours relative to analysis time)
+ call nc_diag_metadata_to_single("Obs_Time",dtime,time_offset,'-')
- call nc_diag_metadata("Scan_Position", sngl(data_s(iscan_pos,n)) ) ! sensor scan position
- call nc_diag_metadata("Sat_Zenith_Angle", sngl(zasat*rad2deg) ) ! satellite zenith angle (degrees)
- call nc_diag_metadata("Sat_Azimuth_Angle", sngl(data_s(ilazi_ang,n)) ) ! satellite azimuth angle (degrees)
- call nc_diag_metadata("Sol_Zenith_Angle", sngl(pangs) ) ! solar zenith angle (degrees)
- call nc_diag_metadata("Sol_Azimuth_Angle", sngl(data_s(isazi_ang,n)) ) ! solar azimuth angle (degrees)
- call nc_diag_metadata("Sun_Glint_Angle", sngl(sgagl) ) ! sun glint angle (degrees) (sgagl)
- call nc_diag_metadata("Scan_Angle", sngl(data_s(iscan_ang,n)*rad2deg) ) ! scan angle
+ call nc_diag_metadata_to_single("Scan_Position",data_s(iscan_pos,n) ) ! sensor scan position
+ call nc_diag_metadata_to_single("Sat_Zenith_Angle", zasat,rad2deg,'*') ! satellite zenith angle (degrees)
+ call nc_diag_metadata_to_single("Sat_Azimuth_Angle",data_s(ilazi_ang,n) ) ! satellite azimuth angle (degrees)
+ call nc_diag_metadata_to_single("Sol_Zenith_Angle",pangs ) ! solar zenith angle (degrees)
+ call nc_diag_metadata_to_single("Sol_Azimuth_Angle",data_s(isazi_ang,n) ) ! solar azimuth angle (degrees)
+ call nc_diag_metadata_to_single("Sun_Glint_Angle",sgagl ) ! sun glint angle (degrees) (sgagl)
+ call nc_diag_metadata_to_single("Scan_Angle",data_s(iscan_ang,n),rad2deg,'*' ) ! scan angle
- call nc_diag_metadata("Water_Fraction", sngl(surface(1)%water_coverage) ) ! fractional coverage by water
- call nc_diag_metadata("Land_Fraction", sngl(surface(1)%land_coverage) ) ! fractional coverage by land
- call nc_diag_metadata("Ice_Fraction", sngl(surface(1)%ice_coverage) ) ! fractional coverage by ice
- call nc_diag_metadata("Snow_Fraction", sngl(surface(1)%snow_coverage) ) ! fractional coverage by snow
+ call nc_diag_metadata_to_single("Water_Fraction",surface(1)%water_coverage ) ! fractional coverage by water
+ call nc_diag_metadata_to_single("Land_Fraction",surface(1)%land_coverage ) ! fractional coverage by land
+ call nc_diag_metadata_to_single("Ice_Fraction",surface(1)%ice_coverage ) ! fractional coverage by ice
+ call nc_diag_metadata_to_single("Snow_Fraction",surface(1)%snow_coverage ) ! fractional coverage by snow
+ call nc_diag_metadata_to_single("fractionOfClearPixelsInFOV",cloud_frac ) ! fractional coverage by snow
if(.not. retrieval)then
- call nc_diag_metadata("Water_Temperature", sngl(surface(1)%water_temperature) ) ! surface temperature over water (K)
- call nc_diag_metadata("Land_Temperature", sngl(surface(1)%land_temperature) ) ! surface temperature over land (K)
- call nc_diag_metadata("Ice_Temperature", sngl(surface(1)%ice_temperature) ) ! surface temperature over ice (K)
- call nc_diag_metadata("Snow_Temperature", sngl(surface(1)%snow_temperature) ) ! surface temperature over snow (K)
- call nc_diag_metadata("Soil_Temperature", sngl(surface(1)%soil_temperature) ) ! soil temperature (K)
- call nc_diag_metadata("Soil_Moisture", sngl(surface(1)%soil_moisture_content) ) ! soil moisture
+ call nc_diag_metadata_to_single("Water_Temperature",surface(1)%water_temperature ) ! surface temperature over water (K)
+ call nc_diag_metadata_to_single("Land_Temperature",surface(1)%land_temperature ) ! surface temperature over land (K)
+ call nc_diag_metadata_to_single("Ice_Temperature",surface(1)%ice_temperature ) ! surface temperature over ice (K)
+ call nc_diag_metadata_to_single("Snow_Temperature",surface(1)%snow_temperature ) ! surface temperature over snow (K)
+ call nc_diag_metadata_to_single("Soil_Temperature",surface(1)%soil_temperature ) ! soil temperature (K)
+ call nc_diag_metadata_to_single("Soil_Moisture",surface(1)%soil_moisture_content ) ! soil moisture
call nc_diag_metadata("Land_Type_Index", surface(1)%land_type ) ! surface land type
- call nc_diag_metadata("tsavg5", missing ) ! SST first guess used for SST retrieval
- call nc_diag_metadata("sstcu", missing ) ! NCEP SST analysis at t
- call nc_diag_metadata("sstph", missing ) ! Physical SST retrieval
- call nc_diag_metadata("sstnv", missing ) ! Navy SST retrieval
+ call nc_diag_metadata("tsavg5", tsavg5 ) ! SST first guess used for SST retrieval
+ call nc_diag_metadata("sstcu", missing ) ! NCEP SST analysis at t
+ call nc_diag_metadata("sstph", missing ) ! Physical SST retrieval
+ call nc_diag_metadata("sstnv", missing ) ! Navy SST retrieval
call nc_diag_metadata("dta", missing ) ! d(ta) corresponding to sstph
call nc_diag_metadata("dqa", missing ) ! d(qa) corresponding to sstph
- call nc_diag_metadata("dtp_avh", missing ) ! data type
+ call nc_diag_metadata("dtp_avh", missing ) ! data type
else
call nc_diag_metadata("Water_Temperature", missing ) ! surface temperature over water (K)
call nc_diag_metadata("Land_Temperature", missing ) ! surface temperature over land (K)
@@ -2614,27 +2693,32 @@ subroutine contents_netcdf_diag_(odiags,idv,iob)
call nc_diag_metadata("Soil_Temperature", missing ) ! soil temperature (K)
call nc_diag_metadata("Soil_Moisture", missing ) ! soil moisture
call nc_diag_metadata("Land_Type_Index", imissing ) ! surface land type
- call nc_diag_metadata("tsavg5", sngl(tsavg5) ) ! SST first guess used for SST retrieval
- call nc_diag_metadata("sstcu", sngl(sstcu) ) ! NCEP SST analysis at t
- call nc_diag_metadata("sstph", sngl(sstph) ) ! Physical SST retrieval
- call nc_diag_metadata("sstnv", sngl(sstnv) ) ! Navy SST retrieval
- call nc_diag_metadata("dta", sngl(dta) ) ! d(ta) corresponding to sstph
- call nc_diag_metadata("dqa", sngl(dqa) ) ! d(qa) corresponding to sstph
- call nc_diag_metadata("dtp_avh", sngl(dtp_avh) ) ! data type
+ call nc_diag_metadata_to_single("tsavg5",tsavg5 ) ! SST first guess used for SST retrieval
+ call nc_diag_metadata_to_single("sstcu",sstcu ) ! NCEP SST analysis at t
+ call nc_diag_metadata_to_single("sstph",sstph ) ! Physical SST retrieval
+ call nc_diag_metadata_to_single("sstnv",sstnv ) ! Navy SST retrieval
+ call nc_diag_metadata_to_single("dta",dta ) ! d(ta) corresponding to sstph
+ call nc_diag_metadata_to_single("dqa",dqa ) ! d(qa) corresponding to sstph
+ call nc_diag_metadata_to_single("dtp_avh",dtp_avh ) ! data type
endif
- call nc_diag_metadata("Vegetation_Fraction", sngl(surface(1)%vegetation_fraction) )
- call nc_diag_metadata("Snow_Depth", sngl(surface(1)%snow_depth) )
- call nc_diag_metadata("tpwc", sngl(tpwc_obs) )
- call nc_diag_metadata("clw_guess_retrieval", sngl(clw_guess_retrieval) )
-
- call nc_diag_metadata("Sfc_Wind_Speed", sngl(surface(1)%wind_speed) )
- call nc_diag_metadata("Cloud_Frac", sngl(cld) )
- call nc_diag_metadata("CTP", sngl(cldp) )
- call nc_diag_metadata("CLW", sngl(clw_obs) )
- call nc_diag_metadata("TPWC", sngl(tpwc_obs) )
- call nc_diag_metadata("clw_obs", sngl(clw_obs) )
- call nc_diag_metadata("clw_guess", sngl(clw_guess) )
+ call nc_diag_metadata_to_single("Vegetation_Fraction",surface(1)%vegetation_fraction )
+ call nc_diag_metadata_to_single("Snow_Depth",surface(1)%snow_depth )
+ call nc_diag_metadata_to_single("tpwc",tpwc_obs )
+ call nc_diag_metadata_to_single("clw_guess_retrieval",clw_guess_retrieval )
+
+ call nc_diag_metadata_to_single("Sfc_Wind_Speed", surface(1)%wind_speed)
+ call nc_diag_metadata_to_single("Cloud_Frac", cld)
+ call nc_diag_metadata_to_single("cloudAmountInSegment", cld) !emily
+ call nc_diag_metadata_to_single("amountSegmentCloudFree",100.0-cld) !emily
+ call nc_diag_metadata_to_single("CTP", cldp)
+ call nc_diag_metadata_to_single("CLW", clw_obs)
+ call nc_diag_metadata_to_single("TPWC", tpwc_obs)
+ call nc_diag_metadata_to_single("clw_obs", clw_obs)
+ call nc_diag_metadata_to_single("clw_guess", clw_guess)
+ call nc_diag_metadata_to_single("factch6", factch6)
+ call nc_diag_metadata_to_single("factch4", factch4) !emily
+ call nc_diag_metadata_to_single("qc4emiss", qc4emiss_out) !emily
if (nstinfo==0) then
data_s(itref,n) = missing
@@ -2643,21 +2727,117 @@ subroutine contents_netcdf_diag_(odiags,idv,iob)
data_s(itz_tr,n) = missing
endif
- call nc_diag_metadata("Foundation_Temperature", sngl(data_s(itref,n)) ) ! reference temperature (Tr) in NSST
- call nc_diag_metadata("SST_Warm_layer_dt", sngl(data_s(idtw,n)) ) ! dt_warm at zob
- call nc_diag_metadata("SST_Cool_layer_tdrop", sngl(data_s(idtc,n)) ) ! dt_cool at zob
- call nc_diag_metadata("SST_dTz_dTfound", sngl(data_s(itz_tr,n)) ) ! d(Tz)/d(Tr)
+ call nc_diag_metadata_to_single("Foundation_Temperature",data_s(itref,n) ) ! reference temperature (Tr) in NSST
+ call nc_diag_metadata_to_single("SST_Warm_layer_dt",data_s(idtw,n) ) ! dt_warm at zob
+ call nc_diag_metadata_to_single("SST_Cool_layer_tdrop",data_s(idtc,n) ) ! dt_cool at zob
+ call nc_diag_metadata_to_single("SST_dTz_dTfound",data_s(itz_tr,n) ) ! d(Tz)/d(Tr)
+
+ call nc_diag_metadata_to_single("standard_deviation_clear_bt", tb_obs_sdv(ich_diag(i))) ! needed for seviri qc
+ call nc_diag_metadata_to_single("Observation", tb_obs0(ich_diag(i))) ! observed brightness temperature (K)
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted", tbcnob(ich_diag(i))) ! observed - simulated Tb with no bias correction (K)
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted", tbc0(ich_diag(i) )) ! observed - simulated Tb with bias corrrection (K)
+ call nc_diag_metadata_to_single("TotalBias", totbc(ich_diag(i) )) ! total bias corrrection (K) !emily
+ call nc_diag_metadata_to_single("Forecast_unadjusted", tsim(ich_diag(i) )) ! simulated Tb without bias corrrection (K)
+ call nc_diag_metadata_to_single("Forecast_adjusted", tsim(ich_diag(i) ) &
+ + totbc(ich_diag(i) )) ! simulated Tb with bias corrrection (K)
+ ! errinv = sqrt(varinv0(ich_diag(i))) !orig
+ errinv = sqrt(varinv(ich_diag(i))) !emily
+ call nc_diag_metadata_to_single("Inverse_Observation_Error", errinv) ! 1.0/observation error
+ call nc_diag_metadata_to_single("Input_Observation_Error", error0(ich_diag(i))) ! Origial error assignment
+!>>emily
+ if (iasi .or. cris .or. airs .or. avhrr) then
+ errinv_tmp = sqrt(varinv_after_wavenum(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_wavenum", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_rangechk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_range", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_topo(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_topo", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_transmittop(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_transmittop", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_clddet(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_clddet", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_jsfcchk_land(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_jsfcchk_land", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_nsstret(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_nsstret", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_jsfcchk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_jsfcchk", errinv_tmp)
+ endif
+
+ if (amsua .or. atms) then
+ errinv_tmp = sqrt(varinv_after_jsfcchk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_jsfcchk", errinv_tmp )
+ errinv_tmp = sqrt(varinv_after_sdoei(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_sdoei", errinv_tmp)
+ errinv_tmp = sqrt(varinv_sdoei(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_sdoei", errinv_tmp)
+ errinv_tmp = sqrt(varinv_grosschk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_grosschk", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_grosschk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_grosschk", errinv_tmp)
+ output_tmp = cldeff_obs(ich_diag(i))
+ call nc_diag_metadata_to_single("cldeff_obs", output_tmp)
+ output_tmp = cldeff_fg(ich_diag(i))
+ call nc_diag_metadata_to_single("cldeff_bkg", output_tmp)
+ endif
+
+ if (ssmis) then
+ errinv_tmp = sqrt(varinv_after_grossroutinechk_over_ocean(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_grossroutinechk_ocean", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_grossroutinechk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_grossroutinechk", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_topo(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_topo", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_sfcchk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_sfcchk", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_ch2chk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_ch2chk", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_scatteringchk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_scatteringchk", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_jsfcchk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_jsfcchk", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_nsstret(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_nsstret", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_grosschk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_grosschk", errinv_tmp)
+ call nc_diag_metadata_to_single("SSMIS_ScatteringIndexPred9", pred9)
+ call nc_diag_metadata_to_single("SSMIS_ScatteringIndexPred10", pred10)
+ call nc_diag_metadata_to_single("SSMIS_ScatteringIndexPred11", pred11)
+ endif
+
+ if (seviri) then
+ errinv_tmp = sqrt(varinv_after_sfcterrianchk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_sfcterrianchk", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_rangechk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_range", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_topo(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_topo", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_transmittop(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_transmittop", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_clddet(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_clddet", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_stdchk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_stdchk", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_grossroutinechk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_grossroutinechk", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_stdadj(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_stdadj", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_nsstret(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_nsstret", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_jsfcchk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_jsfcchk", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_clrfracchk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_clrfracchk", errinv_tmp)
+ errinv_tmp = sqrt(varinv_after_grosschk(ich_diag(i)))
+ call nc_diag_metadata_to_single("Inverse_Observation_Error_after_grosschk", errinv_tmp)
+ endif
+!< rsig)ratio_errors = zero
+ wgesin=zero
! Interpolate guess u, v, and w to observation location and time.
call tintrp31(ges_u,ugesin,dlat,dlon,dpres,dtime,&
@@ -788,7 +788,7 @@ subroutine setuprw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsa
end if
end if
-! Gross error checks
+ ! Gross error checks
obserror = one/max(ratio_errors*error,tiny_r_kind)
obserrlm = max(cermin(ikx),min(cermax(ikx),obserror))
residual = abs(ddiff)
@@ -871,7 +871,7 @@ subroutine setuprw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsa
jiter=jiter, muse=muse(i), nldepart=ddiff)
end if
endif
-
+
! If obs is "acceptable", load array with obs info for use
! in inner loop minimization (int* and stp* routines)
if ( .not. last .and. muse(i)) then
@@ -903,6 +903,7 @@ subroutine setuprw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsa
my_head%b = cvar_b(ikx)
my_head%pg = cvar_pg(ikx)
+
if (luse_obsdiag) then
call obsdiagNode_assert(my_diag,my_head%idv,my_head%iob,1,myname,'my_diag:my_head')
my_head%diags => my_diag
@@ -972,7 +973,7 @@ subroutine check_vars_ (proceed, include_w)
call gsi_metguess_get ('var::v' , ivar, istatus )
proceed=proceed.and.ivar>0
call gsi_metguess_get ('var::w' , ivar, istatus )
- if (ivar>0) then
+ if (if_use_w_vr.and.ivar>0) then
include_w=.true.
if(if_vterminal)then
if( .not. if_model_dbz ) then
@@ -992,8 +993,9 @@ subroutine check_vars_ (proceed, include_w)
endif
end subroutine check_vars_
- subroutine init_vars_
+ subroutine init_vars_(include_w)
+ logical,intent(in ):: include_w
real(r_kind),dimension(:,: ),pointer:: rank2=>NULL()
real(r_kind),dimension(:,:,:),pointer:: rank3=>NULL()
character(len=5) :: varname
@@ -1319,30 +1321,30 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_metadata("Observation_Class", obsclass )
call nc_diag_metadata("Observation_Type", ictype(ikx) )
call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
- call nc_diag_metadata("Station_Elevation", sngl(data(ielev,i)) )
- call nc_diag_metadata("Pressure", sngl(presw) )
- call nc_diag_metadata("Height", sngl(data(ihgt,i)) )
- call nc_diag_metadata("Time", sngl(dtime-time_offset))
- call nc_diag_metadata("Prep_QC_Mark", sngl(zero) )
- call nc_diag_metadata("Prep_Use_Flag", sngl(data(iuse,i)) )
+ call nc_diag_metadata_to_single("Latitude",data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude",data(ilone,i) )
+ call nc_diag_metadata_to_single("Station_Elevation",data(ielev,i) )
+ call nc_diag_metadata_to_single("Pressure",presw )
+ call nc_diag_metadata_to_single("Height",data(ihgt,i) )
+ call nc_diag_metadata_to_single("Time",dtime,time_offset,'-')
+ call nc_diag_metadata("Prep_QC_Mark", 0.0_r_single )
+ call nc_diag_metadata_to_single("Prep_Use_Flag",data(iuse,i) )
! call nc_diag_metadata("Nonlinear_QC_Var_Jb", var_jb )
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",rwgt )
if(muse(i)) then
- call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
+ call nc_diag_metadata("Analysis_Use_Flag", 1.0_r_single )
else
- call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
+ call nc_diag_metadata("Analysis_Use_Flag", -1.0_r_single )
endif
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
+ call nc_diag_metadata_to_single("Errinv_Input",errinv_input )
+ call nc_diag_metadata_to_single("Errinv_Adjust",errinv_adjst )
+ call nc_diag_metadata_to_single("Errinv_Final",errinv_final )
+
+ call nc_diag_metadata_to_single("Observation",data(irwob,i) )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",ddiff )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted",data(irwob,i),rwwind,'-')
- call nc_diag_metadata("Observation", sngl(data(irwob,i)) )
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ddiff) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(data(irwob,i)-rwwind) )
-
if (lobsdiagsave) then
do jj=1,miter
if (odiag%muse(jj)) then
@@ -1351,18 +1353,18 @@ subroutine contents_netcdf_diag_(odiag)
obsdiag_iuse(jj) = -one
endif
enddo
-
+
call nc_diag_data2d("ObsDiagSave_iuse", obsdiag_iuse )
call nc_diag_data2d("ObsDiagSave_nldepart", odiag%nldepart )
call nc_diag_data2d("ObsDiagSave_tldepart", odiag%tldepart )
- call nc_diag_data2d("ObsDiagSave_obssen", odiag%obssen )
+ call nc_diag_data2d("ObsDiagSave_obssen", odiag%obssen )
endif
if (save_jacobian) then
call nc_diag_data2d("Observation_Operator_Jacobian_stind", dhx_dx%st_ind)
call nc_diag_data2d("Observation_Operator_Jacobian_endind", dhx_dx%end_ind)
call nc_diag_data2d("Observation_Operator_Jacobian_val", real(dhx_dx%val,r_single))
endif
-
+
end subroutine contents_netcdf_diag_
subroutine final_vars_
diff --git a/src/gsi/setupspd.f90 b/src/gsi/setupspd.f90
index 91b2467bf3..600533ecb7 100644
--- a/src/gsi/setupspd.f90
+++ b/src/gsi/setupspd.f90
@@ -114,7 +114,7 @@ subroutine setupspd(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diags
use obsmod, only: netcdf_diag, binary_diag, dirname, ianldate
use obsmod, only: l_obsprvdiag
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim, nc_diag_read_close
use m_obsNode, only: obsNode
use m_spdNode, only: spdNode
@@ -301,7 +301,7 @@ subroutine setupspd(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diags
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
dup=one
@@ -504,7 +504,7 @@ subroutine setupspd(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diags
spdges=sqrt(ugesin*ugesin+vgesin*vgesin)
iz = max(1, min( int(dpres), nsig))
- delz = max(zero, min(dpres - float(iz), one))
+ delz = max(zero, min(dpres - real(iz,r_kind), one))
if (save_jacobian) then
@@ -949,29 +949,29 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_metadata("Observation_Class", obsclass )
call nc_diag_metadata("Observation_Type", ictype(ikx) )
call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
- call nc_diag_metadata("Station_Elevation", sngl(data(istnelv,i)) )
- call nc_diag_metadata("Pressure", sngl(presw) )
- call nc_diag_metadata("Height", sngl(data(ihgt,i)) )
- call nc_diag_metadata("Time", sngl(dtime-time_offset))
- call nc_diag_metadata("Prep_QC_Mark", sngl(data(iqc,i)) )
- call nc_diag_metadata("Prep_Use_Flag", sngl(data(iuse,i)) )
+ call nc_diag_metadata_to_single("Latitude",data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude",data(ilone,i) )
+ call nc_diag_metadata_to_single("Station_Elevation",data(istnelv,i) )
+ call nc_diag_metadata_to_single("Pressure",presw )
+ call nc_diag_metadata_to_single("Height",data(ihgt,i) )
+ call nc_diag_metadata_to_single("Time",dtime,time_offset,'-')
+ call nc_diag_metadata_to_single("Prep_QC_Mark",data(iqc,i) )
+ call nc_diag_metadata_to_single("Prep_Use_Flag",data(iuse,i) )
! call nc_diag_metadata("Nonlinear_QC_Var_Jb", var_jb )
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",rwgt )
if(muse(i)) then
- call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
+ call nc_diag_metadata("Analysis_Use_Flag", 1.0_r_single )
else
- call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
+ call nc_diag_metadata("Analysis_Use_Flag", -1.0_r_single )
endif
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
+ call nc_diag_metadata_to_single("Errinv_Input",errinv_input )
+ call nc_diag_metadata_to_single("Errinv_Adjust",errinv_adjst )
+ call nc_diag_metadata_to_single("Errinv_Final",errinv_final )
- call nc_diag_metadata("Observation", sngl(spdob) )
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ddiff) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(spdob0-spdges) )
+ call nc_diag_metadata_to_single("Observation",spdob )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",ddiff )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted", spdob0,spdges,'-')
if (lobsdiagsave) then
do jj=1,miter
diff --git a/src/gsi/setupsst.f90 b/src/gsi/setupsst.f90
index 6562d0392f..994638142a 100644
--- a/src/gsi/setupsst.f90
+++ b/src/gsi/setupsst.f90
@@ -99,7 +99,7 @@ subroutine setupsst(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diags
use obsmod, only: luse_obsdiag
use obsmod, only: netcdf_diag, binary_diag, dirname,ianldate
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim, nc_diag_read_close
use gsi_4dvar, only: nobs_bins,hr_obsbin
use oneobmod, only: magoberr,maginnov,oneobtest
@@ -585,35 +585,35 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_metadata("Observation_Class", obsclass )
call nc_diag_metadata("Observation_Type", ictype(ikx) )
call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
- call nc_diag_metadata("Station_Elevation", sngl(data(istnelv,i)) )
+ call nc_diag_metadata_to_single("Latitude",data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude",data(ilone,i) )
+ call nc_diag_metadata_to_single("Station_Elevation",data(istnelv,i) )
call nc_diag_metadata("Pressure", missing )
- call nc_diag_metadata("Height", sngl(data(izob,i)) )
- call nc_diag_metadata("Time", sngl(dtime-time_offset))
- call nc_diag_metadata("Prep_QC_Mark", sngl(data(ipct,i)) )
- call nc_diag_metadata("Prep_Use_Flag", sngl(data(iuse,i)) )
+ call nc_diag_metadata_to_single("Height",data(izob,i) )
+ call nc_diag_metadata_to_single("Time",dtime,time_offset,'-')
+ call nc_diag_metadata_to_single("Prep_QC_Mark",data(ipct,i) )
+ call nc_diag_metadata_to_single("Prep_Use_Flag",data(iuse,i) )
! call nc_diag_metadata("Nonlinear_QC_Var_Jb", var_jb )
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",rwgt )
if(muse(i)) then
- call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
+ call nc_diag_metadata("Analysis_Use_Flag", 1.0_r_single )
else
- call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
+ call nc_diag_metadata("Analysis_Use_Flag", -1.0_r_single )
endif
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
+ call nc_diag_metadata_to_single("Errinv_Input",errinv_input )
+ call nc_diag_metadata_to_single("Errinv_Adjust",errinv_adjst )
+ call nc_diag_metadata_to_single("Errinv_Final",errinv_final )
- call nc_diag_metadata("Observation", sngl(data(isst,i)) )
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ddiff) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(data(isst,i)-sstges) )
+ call nc_diag_metadata_to_single("Observation",data(isst,i) )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",ddiff )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted",data(isst,i),sstges,'-')
if (nst_gsi>0) then
- call nc_diag_metadata("FoundationTempBG", sngl(data(itref,i)) )
- call nc_diag_metadata("DiurnalWarming_at_zob", sngl(data(idtw,i)) )
- call nc_diag_metadata("SkinLayerCooling_at_zob", sngl(data(idtw,i)) )
- call nc_diag_metadata("Sensitivity_Tzob_Tr", sngl(data(itz_tr,i)) )
+ call nc_diag_metadata_to_single("FoundationTempBG",data(itref,i) )
+ call nc_diag_metadata_to_single("DiurnalWarming_at_zob",data(idtw,i) )
+ call nc_diag_metadata_to_single("SkinLayerCooling_at_zob",data(idtc,i) )
+ call nc_diag_metadata_to_single("Sensitivity_Tzob_Tr",data(itz_tr,i) )
endif
if (lobsdiagsave) then
diff --git a/src/gsi/setupswcp.f90 b/src/gsi/setupswcp.f90
index c65ad1495c..bd9c1e9690 100644
--- a/src/gsi/setupswcp.f90
+++ b/src/gsi/setupswcp.f90
@@ -67,7 +67,7 @@ subroutine setupswcp(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diag
use obsmod, only: netcdf_diag, binary_diag, dirname
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header,nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init,nc_diag_read_get_dim,nc_diag_read_close
use state_vectors, only: svars3d, levels
@@ -268,7 +268,7 @@ subroutine setupswcp(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diag
iobshgt=16 ! index of observation height (m)
do i=1,nobs
- muse(i)=nint(data(11,i)) <= jiter
+ muse(i)=nint(data(11,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
dup=one
@@ -893,28 +893,28 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_metadata("Observation_Class", obsclass )
call nc_diag_metadata("Observation_Type", ictype(ikx) )
call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
- call nc_diag_metadata("Station_Elevation", sngl(data(istnelv,i)) )
- call nc_diag_metadata("Pressure", sngl(data(iobsprs,i)) )
- call nc_diag_metadata("Height", sngl(data(iobshgt,i)) )
- call nc_diag_metadata("Time", sngl(dtime-time_offset))
- call nc_diag_metadata("Prep_QC_Mark", sngl(data(iqc,i)) )
- call nc_diag_metadata("Setup_QC_Mark", sngl(rmiss_single) )
- call nc_diag_metadata("Prep_Use_Flag", sngl(data(iuse,i)) )
+ call nc_diag_metadata_to_single("Latitude",data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude",data(ilone,i) )
+ call nc_diag_metadata_to_single("Station_Elevation",data(istnelv,i) )
+ call nc_diag_metadata_to_single("Pressure",data(iobsprs,i) )
+ call nc_diag_metadata_to_single("Height",data(iobshgt,i) )
+ call nc_diag_metadata_to_single("Time",dtime,time_offset,'-')
+ call nc_diag_metadata_to_single("Prep_QC_Mark",data(iqc,i) )
+ call nc_diag_metadata("Setup_QC_Mark",rmiss_single )
+ call nc_diag_metadata_to_single("Prep_Use_Flag",data(iuse,i) )
if(muse(i)) then
call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
else
call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
endif
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
- call nc_diag_metadata("Observation", sngl(dswcp) )
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ddiff) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(dswcp-swcpges))
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",rwgt )
+ call nc_diag_metadata_to_single("Errinv_Input",errinv_input )
+ call nc_diag_metadata_to_single("Errinv_Adjust",errinv_adjst )
+ call nc_diag_metadata_to_single("Errinv_Final",errinv_final )
+ call nc_diag_metadata_to_single("Observation",dswcp )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",ddiff )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted", dswcp,swcpges,'-')
if (lobsdiagsave) then
do jj=1,miter
diff --git a/src/gsi/setupt.f90 b/src/gsi/setupt.f90
index 815c16014d..0fd4691386 100644
--- a/src/gsi/setupt.f90
+++ b/src/gsi/setupt.f90
@@ -42,7 +42,7 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
use obsmod, only: netcdf_diag, binary_diag, dirname
use obsmod, only: l_obsprvdiag
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim, nc_diag_read_close
use qcmod, only: npres_print,dfact,dfact1,ptop,pbot,buddycheck_t
@@ -54,11 +54,12 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
use gridmod, only: nsig,twodvar_regional,regional
use gridmod, only: get_ijk,pt_ll
- use jfunc, only: jiter,last,jiterstart,miter
+ use jfunc, only: jiter,last,jiterstart,miter,hofx_2m_sfcfile
use guess_grids, only: nfldsig, hrdifsig,ges_lnprsl,&
geop_hgtl,ges_tsen,pbl_height
- use state_vectors, only: svars3d, levels
+ use guess_grids, only: ges_prsi
+ use state_vectors, only: svars3d, levels, ns3d, svars2d
use constants, only: zero, one, four,t0c,rd_over_cp,three,rd_over_cp_mass,ten
use constants, only: tiny_r_kind,half,two
@@ -228,6 +229,8 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
! for 3D-RTMA (if l_obsprvdiag is true).
! 2022-03-15 Hu change all th2 to t2m to indicate that 2m temperature
! is sensible instead of potentionl temperature
+! 2023-03-21 Draper added option to interpolate screen-level T from model 2m output.
+! (hofx_2m_sfcfile)
!
! !REMARKS:
! language: f90
@@ -277,16 +280,24 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
real(r_kind),dimension(npredt):: pred
real(r_kind),dimension(npredt):: predcoef
real(r_kind) tgges,roges
- real(r_kind),dimension(nsig):: tvtmp,qtmp,utmp,vtmp,hsges
+ real(r_kind),dimension(nsig):: ttmp,tvtmp,qtmp,utmp,vtmp,hsges
real(r_kind) u10ges,v10ges,t2ges,q2ges,psges2,f10ges
real(r_kind),dimension(34) :: ptablt
real(r_single),allocatable,dimension(:,:)::rdiagbuf
real(r_single),allocatable,dimension(:,:)::rdiagbufp
+ ! GSI profiles are stored with bottom up index; output the profiles
+ ! with top down index
+ real(r_kind),dimension(nsig):: ttmp_reverse,tvtmp_reverse,qtmp_reverse,utmp_reverse,vtmp_reverse
+ real(r_kind),dimension(nsig):: hsges_reverse, zges_reverse,prsltmp2_reverse
+ real(r_kind),dimension(nsig):: zges_read_reverse, zges_geometric_reverse
+ real(r_kind),dimension(nsig+1):: prsitmp_reverse
+ !<< JEDI
real(r_kind),dimension(nsig):: prsltmp2
+ real(r_kind),dimension(nsig+1):: prsitmp
- integer(i_kind) i,j,nchar,nreal,k,ii,iip,jj,l,nn,ibin,idia,idia0,ix,ijb
+ integer(i_kind) i,j,nchar,nreal,k,kk,ii,iip,jj,l,nn,ibin,idia,idia0,ix,ijb
integer(i_kind) mm1,jsig,iqt
integer(i_kind) itype,msges
integer(i_kind) ier,ilon,ilat,ipres,itob,id,itime,ikx,iqc,iptrb,icat,ipof,ivvlc,idx
@@ -309,7 +320,7 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
logical,dimension(nobs):: luse,muse
integer(i_kind),dimension(nobs):: ioid ! initial (pre-distribution) obs ID
- logical sfctype
+ logical sfctype, landsfctype
logical iqtflg
logical aircraftobst
logical duplogic
@@ -342,6 +353,18 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
integer(i_kind):: ich0
type(obsLList),pointer,dimension(:):: thead
+
+ real(r_kind) :: delta_z, lapse_error
+ real(r_kind), parameter :: T_lapse = -0.0045 ! standard lapse rate, K/m
+! use 4.5 K/km, in place of more standard 6.5 K/km, following
+! https://agupubs.onlinelibrary.wiley.com/doi/10.1029/2019EA000984
+! lapse_error_frac around 0.5 ~ 2K/km, from Figure 2 of above.
+ real(r_kind), parameter :: lapse_error_frac = 0.5 ! inflation factor for obs error when vertically interpolating
+ real(r_kind), parameter :: max_delta_z = 300. ! max. vertical mismatch allowed
+
+! CSD - move this to where the namelists are read in.
+ if (i_use_2mt4b>0) hofx_2m_sfcfile=.false.
+
thead => obsLL(:)
save_jacobian = conv_diagsave .and. jiter==jiterstart .and. lobsdiag_forenkf
@@ -398,7 +421,7 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
end if
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! If HD raobs available move prepbufr version to monitor
if(nhdt > 0)then
@@ -432,8 +455,11 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
hr_offset=min_offset/60.0_r_kind
dup=one
do k=1,nobs
+ ikx=nint(data(ikxx,k))
+ itype=ictype(ikx)
+ landsfctype =( itype==181 .or. itype==183 .or. itype==187 )
do l=k+1,nobs
- if (twodvar_regional) then
+ if (twodvar_regional .or. (hofx_2m_sfcfile .and. landsfctype) ) then
duplogic=data(ilat,k) == data(ilat,l) .and. &
data(ilon,k) == data(ilon,l) .and. &
data(ier,k) < r1000 .and. data(ier,l) < r1000 .and. &
@@ -465,6 +491,7 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
end do
! Run a buddy-check
+! Note: buddy check crashes for hofx_2m_sfcfile option.
if (twodvar_regional .and. buddycheck_t) call buddy_check_t(is,data,luse,mype,nele,nobs,muse,buddyuse)
! If requested, save select data for output to diagnostic file
@@ -494,7 +521,7 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
if(netcdf_diag) call init_netcdf_diag_
end if
scale=one
- rsig=float(nsig)
+ rsig=real(nsig,r_kind)
mm1=mype+1
! rsli=isli
@@ -521,6 +548,10 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
rstation_id = data(id,i)
prest=r10*exp(dpres) ! in mb
sfctype=(itype>179.and.itype<190).or.(itype>=192.and.itype<=199)
+! hofx_2m_sfcfile option to calculate hofx from 2m model output (rather than LML)
+! is restricted to landsfctype only. GDAS assimilates 180 and 182 over ocean,
+! should we also use 2m model output for the over-ocean obs?
+ landsfctype =( itype==181 .or. itype==183 .or. itype==187 )
iqtflg=nint(data(iqt,i)) == 0
var_jb=data(ijb,i)
@@ -573,6 +604,57 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
if(.not.in_curbin) cycle
+!>>JEDI
+! GEOVALS for UFO eval
+ psges2 = psges ! keep in cb
+ prsltmp2 = exp(prsltmp)
+ call tintrp2a1(ges_prsi,prsitmp,dlat,dlon,dtime,hrdifsig,&
+ nsig+1,mype,nfldsig)
+ call tintrp2a1(ges_tv,tvtmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(ges_tsen,ttmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(ges_q,qtmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(ges_u,utmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(ges_v,vtmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(geop_hgtl,hsges,dlat,dlon,dtime,hrdifsig,& !orig
+ nsig,mype,nfldsig)
+ ! geopotential height at obs location (lat/lon) and time
+ !xxx call tintrp2a1(geop_hgtl,zges_read,dlat,dlon,dtime,hrdifsig, &
+ !xxx nsig,mype,nfldsig)
+ ! model virtual temperature (ges_tv) at obs location (lat/lon)
+ ! obs time, and model surface (lower model level)
+ !xxx call tintrp31(ges_tv,sfctges,dlat,dlon,log(psges),dtime, &
+ !xxx hrdifsig,mype,nfldsig)
+
+! Convert geopotential height at layer midpoints to geometric
+! height using equations (17, 20, 23) in MJ Mahoney's note
+! "A discussion of various measures of altitude" (2001).
+! Available on the web at
+! http://mtp.jpl.nasa.gov/notes/altitude/altitude.html
+!
+! termg = equation 17
+! termr = equation 21
+! termrg = first term in the denominator of equation 23
+! zges = equation 23
+
+!xxx slat = data(ilate,i)*deg2rad
+!xxx sin2 = sin(slat)*sin(slat)
+!xxx termg = grav_equator * &
+!xxx ((one+somigliana*sin2)/sqrt(one-eccentricity*eccentricity*sin2))
+!xxx termr = semi_major_axis /(one + flattening + grav_ratio - &
+!xxx two*flattening*sin2)
+!xxx termrg = (termg/grav)*termr
+!xxx do k=1,nsig
+!xxx zges_geometric(k) = (termr*zges_read(k)) / (termrg-zges_read(k)) ! eq (23)
+!xxx end do
+! END GEOVALS
+!<= 3 mixed
+! for now, use only pure land
+ if (int(data(idomsfc,i)) .NE. 1 ) muse(i) = .false.
+
+ call tintrp2a11(ges_t2m,tges2m,dlat,dlon,dtime,hrdifsig,&
+ mype,nfldsig)
+
+! correct obs to model terrain height using a standard lapse rate.
+! Later: look into updating with lapse-rate from the model (similar to gsd_terrain_match)
+
+ delta_z = data(izz,i) - data(istnelv,i)
+ tob = tob + delta_z*T_lapse
+ !update the station elevation
+ data(istnelv,i) = data(izz,i)
+
+ if(save_jacobian) then
+ t_ind = getindex(svars2d, 't2m')
+ if (t_ind < 0) then
+ print *, 'Error: no variable t2m in state vector.Exiting.'
+ call stop2(1300)
+ endif
+ dhx_dx%st_ind(1) = sum(levels(1:ns3d)) + t_ind
+ dhx_dx%end_ind(1) = sum(levels(1:ns3d)) + t_ind
+ dhx_dx%val(1) = one
+ dhx_dx%val(2) = zero ! in this case, there is no vertical interp
+ ! and nnz (=dim(dhx_dx%val)) should be one,
+ ! but nnz is a file attribute, so need to use
+ ! same value as for vertical profile obs. Get
+ ! around this by setting val(2) to zero.
+ endif
+
+! SCENARIO 3: obs is sfctype, and neither sfcmodel nor hofx_2m_sfcfile is chosen
+! .or. obs is not sfctype. Interpoate hofx from model levels.
else
+
if(iqtflg)then
+! SCENARIO 3a: obs is a virtual temp.
! Interpolate guess tv to observation location and time
call tintrp31(ges_tv,tges,dlat,dlon,dpres,dtime, &
hrdifsig,mype,nfldsig)
iz = max(1, min( int(dpres), nsig))
- delz = max(zero, min(dpres - float(iz), one))
+ delz = max(zero, min(dpres - real(iz,r_kind), one))
if (save_jacobian) then
t_ind = getindex(svars3d, 'tv')
@@ -717,12 +867,13 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
dhx_dx%val(2) = delz ! weight for iz+1's level
endif
else
+! SCENARIO 3b: obs is a sensible temp.
! Interpolate guess tsen to observation location and time
call tintrp31(ges_tsen,tges,dlat,dlon,dpres,dtime, &
hrdifsig,mype,nfldsig)
iz = max(1, min( int(dpres), nsig))
- delz = max(zero, min(dpres - float(iz), one))
+ delz = max(zero, min(dpres - real(iz,r_kind), one))
if (save_jacobian) then
t_ind = getindex(svars3d, 'tsen')
@@ -739,6 +890,8 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
endif
end if
+
+! SCENARIO 4: obs is sfctype, and i_use_2mt4b flag is on (turns on regional sfc DA)
if(i_use_2mt4b>0 .and. sfctype) then
if(i_coastline==1 .or. i_coastline==3) then
@@ -773,17 +926,23 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
call grdcrd1(sfcchk,prsltmp(1),nsig,-1)
! Check to see if observations is above the top of the model (regional mode)
- if(sfctype)then
+ if(sfctype .and. .not. (hofx_2m_sfcfile .and. landsfctype) )then
if(abs(dpres)>four) drpx=1.0e10_r_kind
pres_diff=prest-r10*psges
if (twodvar_regional .and. abs(pres_diff)>=r1000) drpx=1.0e10_r_kind
end if
- rlow=max(sfcchk-dpres,zero)
-! linear variation of observation ramp [between grid points 1(~3mb) and 15(~45mb) below the surface]
- if(l_sfcobserror_ramp_t) then
- ramp=min(max(((rlow-1.0_r_kind)/(15.0_r_kind-1.0_r_kind)),0.0_r_kind),1.0_r_kind)
+
+ if (.not. (hofx_2m_sfcfile .and. landsfctype) ) then
+ rlow=max(sfcchk-dpres,zero)
+! linear variation of observation ramp [between grid points 1(~3mb) and 15(~45mb) below the surface]
+ if(l_sfcobserror_ramp_t) then
+ ramp=min(max(((rlow-1.0_r_kind)/(15.0_r_kind-1.0_r_kind)),0.0_r_kind),1.0_r_kind)
+ else
+ ramp=rlow
+ endif
else
- ramp=rlow
+ rlow = zero
+ ramp = zero
endif
rhgh=max(zero,dpres-rsigp-r0_001)
@@ -795,12 +954,26 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
if(rlow/=zero) awork(2) = awork(2) + one
if(rhgh/=zero) awork(3) = awork(3) + one
end if
-
- ratio_errors=error/(data(ier,i)+drpx+1.0e6_r_kind*rhgh+r8*ramp)
+
+! inflate error for uncertainty in the terrain adjustment
+ lapse_error = 0.
+ if ( hofx_2m_sfcfile .and. landsfctype) then
+ if (abs(delta_z)max_delta_z do not assim.
+ ! inflate obs error to account for error in lapse_rate
+ ! also include some representativity error here (assuming
+ ! delta_z ~ heterogeneity)
+ lapse_error = abs(lapse_error_frac*T_lapse*delta_z)
+ else
+ muse(i)=.false.
+ endif
+ endif
+
+ ratio_errors=error/(data(ier,i)+drpx+1.0e6_r_kind*rhgh+r8*ramp + lapse_error)
! Compute innovation
- if(i_use_2mt4b>0 .and. sfctype) then
+ if( (sfctype .and. i_use_2mt4b>0) .or. (hofx_2m_sfcfile .and. landsfctype) ) then
ddiff = tob-tges2m
+ if (hofx_2m_sfcfile) tges=tges2m
else
ddiff = tob-tges
endif
@@ -1017,6 +1190,7 @@ subroutine setupt(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
my_head%elat= data(ilate,i)
my_head%elon= data(ilone,i)
+ if(npredt <= 0) write(6,*) ' npredt = ',npredt
allocate(my_head%pred(npredt))
! Set (i,j,k) indices of guess gridpoint that bound obs location
@@ -1411,7 +1585,7 @@ subroutine init_vars_
write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
call stop2(999)
endif
- if(i_use_2mt4b>0) then
+ if(i_use_2mt4b>0 .or. hofx_2m_sfcfile) then
! get t2m ...
varname='t2m'
call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank2,istatus)
@@ -1430,6 +1604,7 @@ subroutine init_vars_
write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
call stop2(999)
endif
+
! get q2m ...
varname='q2m'
call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank2,istatus)
@@ -1674,36 +1849,43 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_metadata("Observation_Class", obsclass )
call nc_diag_metadata("Observation_Type", ictype(ikx) )
call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
- call nc_diag_metadata("Station_Elevation", sngl(data(istnelv,i)) )
- call nc_diag_metadata("Pressure", sngl(prest) )
- call nc_diag_metadata("Height", sngl(data(iobshgt,i)) )
- call nc_diag_metadata("Time", sngl(dtime-time_offset))
- call nc_diag_metadata("Prep_QC_Mark", sngl(data(iqc,i)) )
- call nc_diag_metadata("Setup_QC_Mark", sngl(data(iqt,i)) )
- call nc_diag_metadata("Prep_Use_Flag", sngl(data(iuse,i)) )
+ call nc_diag_metadata_to_single("Latitude",data(ilate,i))
+ call nc_diag_metadata_to_single("Longitude",data(ilone,i))
+! this is the obs height after being interpolated to the model (=model height)
+ call nc_diag_metadata_to_single("Station_Elevation",data(istnelv,i))
+ call nc_diag_metadata_to_single("Pressure",prest)
+! this is the original obs height (= stn elevation, before being interpolated)
+ call nc_diag_metadata_to_single("Height",data(iobshgt,i))
+ call nc_diag_metadata_to_single("Time",dtime,time_offset,'-')
+ call nc_diag_metadata_to_single("Prep_QC_Mark",data(iqc,i))
+ call nc_diag_metadata_to_single("Setup_QC_Mark",data(iqt,i))
+ call nc_diag_metadata_to_single("Prep_Use_Flag",data(iuse,i))
+ call nc_diag_metadata("Virtual_Temperature_Flag",nint(data(iqt,i)))
if(muse(i)) then
- call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
+ call nc_diag_metadata_to_single("Analysis_Use_Flag", one)
else
- call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
+ call nc_diag_metadata_to_single("Analysis_Use_Flag", -one)
endif
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
- call nc_diag_metadata("Observation", sngl(data(itob,i)) )
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(ddiff) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(tob-tges) )
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",rwgt)
+ call nc_diag_metadata_to_single("Errinv_Input",errinv_input )
+ call nc_diag_metadata_to_single("Errinv_Adjust",errinv_adjst )
+ call nc_diag_metadata_to_single("Errinv_Final",errinv_final )
+ if (hofx_2m_sfcfile ) then
+ call nc_diag_metadata_to_single("Observation", tob )
+ else
+ call nc_diag_metadata_to_single("Observation", data(itob,i) )
+ endif
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",ddiff )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted",tob,tges,'-')
if (aircraft_t_bc_pof .or. aircraft_t_bc .or. aircraft_t_bc_ext) then
- call nc_diag_metadata("Data_Pof", sngl(data(ipof,i)) )
- call nc_diag_metadata("Data_Vertical_Velocity", sngl(data(ivvlc,i)) )
+ call nc_diag_metadata_to_single("Data_Pof",data(ipof,i))
+ call nc_diag_metadata_to_single("Data_Vertical_Velocity",data(ivvlc,i))
if (npredt .gt. one) then
- call nc_diag_data2d("Bias_Correction_Terms", sngl(predbias) )
+ call nc_diag_data2d("Bias_Correction_Terms", sngl(predbias))
else if (npredt .eq. one) then
- call nc_diag_metadata("Bias_Correction_Terms", sngl(predbias(1)) )
+ call nc_diag_metadata_to_single("Bias_Correction_Terms",predbias(1))
endif
else
call nc_diag_metadata("Data_Pof", missing )
@@ -1712,7 +1894,7 @@ subroutine contents_netcdf_diag_(odiag)
do j=1,npredt
predbias(j) = missing
enddo
- call nc_diag_data2d("Bias_Correction_Terms", sngl(predbias) )
+ call nc_diag_data2d("Bias_Correction_Terms", predbias )
else if (npredt .eq. one) then
call nc_diag_metadata("Bias_Correction_Terms", missing )
endif
@@ -1747,6 +1929,51 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_data2d("Observation_Operator_Jacobian_endind", dhx_dx%end_ind)
call nc_diag_data2d("Observation_Operator_Jacobian_val", real(dhx_dx%val,r_single))
endif
+ ! GEOVALS
+ !>>emily
+ do k = 1, nsig
+ kk = nsig-k+1
+ utmp_reverse(kk) = utmp(k)
+ vtmp_reverse(kk) = vtmp(k)
+ ttmp_reverse(kk) = ttmp(k)
+ !tvtmp_reverse(kk) = tges(k) !emily
+ tvtmp_reverse(kk) = tvtmp(k) !ADC
+ qtmp_reverse(kk) = qtmp(k)
+ hsges_reverse(kk) = hsges(k)
+ !zges_read_reverse(kk)= zges_read(k)
+ !zges_geometric_reverse(kk)= zges_geometric(k)
+ !zges_reverse(kk) = zges(k)
+ prsltmp2_reverse(kk) = prsltmp2(k)
+ enddo
+ do k = 1, nsig+1
+ kk = (nsig+1)-k+1
+ prsitmp_reverse(kk) = prsitmp(k)
+ enddo
+
+ call nc_diag_data2d("atmosphere_pressure_coordinate", sngl(prsltmp2_reverse*r1000))
+ call nc_diag_data2d("atmosphere_pressure_coordinate_interface", sngl(prsitmp_reverse*r1000))
+ call nc_diag_data2d("air_temperature", sngl(ttmp_reverse))
+ call nc_diag_data2d("virtual_temperature", sngl(tvtmp_reverse)) !emily
+ call nc_diag_data2d("specific_humidity", sngl(qtmp_reverse))
+ call nc_diag_data2d("eastward_wind", sngl(utmp_reverse))
+ call nc_diag_data2d("northward_wind", sngl(vtmp_reverse))
+ call nc_diag_data2d("geopotential_height", sngl(hsges_reverse) ) !orig
+! call nc_diag_data2d("geopotential_height", sngl(zges_read_reverse) ) !emily
+! call nc_diag_data2d("geometric_height", sngl(zges_geometric_reverse) )
+! !emily
+ !<>emily
+ do k = 1, nsig
+ kk = nsig-k+1
+ utmp_reverse(kk) = utmp(k)
+ vtmp_reverse(kk) = vtmp(k)
+ ttmp_reverse(kk) = ttmp(k)
+ !tvtmp_reverse(kk) = tges(k) !emily
+ tvtmp_reverse(kk) = tvtmp(k) !ADC
+ qtmp_reverse(kk) = qtmp(k)
+ hsges_reverse(kk) = hsges(k)
+ !zges_read_reverse(kk)= zges_read(k)
+ !zges_geometric_reverse(kk)= zges_geometric(k)
+ !zges_reverse(kk) = zges(k)
+ prsltmp2_reverse(kk) = prsltmp2(k)
+ enddo
+ do k = 1, nsig+1
+ kk = (nsig+1)-k+1
+ prsitmp_reverse(kk) = prsitmp(k)
+ enddo
+
+
+ call nc_diag_data2d("atmosphere_pressure_coordinate", sngl(prsltmp2_reverse*r1000))
+ call nc_diag_data2d("atmosphere_pressure_coordinate_interface", sngl(prsitmp_reverse*r1000))
+ call nc_diag_data2d("air_temperature", sngl(ttmp_reverse))
+ call nc_diag_data2d("virtual_temperature", sngl(tvtmp_reverse)) !emily
+ call nc_diag_data2d("specific_humidity", sngl(qtmp_reverse))
+ call nc_diag_data2d("eastward_wind", sngl(utmp_reverse))
+ call nc_diag_data2d("northward_wind", sngl(vtmp_reverse))
+ call nc_diag_data2d("geopotential_height", sngl(hsges_reverse) ) !orig
+! call nc_diag_data2d("geopotential_height", sngl(zges_read_reverse) ) !emily
+! call nc_diag_data2d("geometric_height", sngl(zges_geometric_reverse) )
+! !emily
+ !<psges)then
imin=l
@@ -692,29 +692,29 @@ subroutine contents_netcdf_diag_(odiag)
call nc_diag_metadata("Observation_Class", obsclass )
call nc_diag_metadata("Observation_Type", ictype(ikx) )
call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
+ call nc_diag_metadata_to_single("Latitude",data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude",data(ilone,i) )
call nc_diag_metadata("Station_Elevation", sngl(zero) )
- call nc_diag_metadata("Pressure", sngl(data(ipres,i)*r10))
- call nc_diag_metadata("Height", sngl(zero) )
- call nc_diag_metadata("Time", sngl(dtime-time_offset))
+ call nc_diag_metadata_to_single("Pressure", data(ipres,i),r10,'*')
+ call nc_diag_metadata_to_single("Height",zero )
+ call nc_diag_metadata_to_single("Time",dtime,time_offset,'-')
call nc_diag_metadata("Prep_QC_Mark", sngl(one) )
call nc_diag_metadata("Prep_Use_Flag", sngl(one) )
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",(rwgt) )
if(muse(i)) then
call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
else
- call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
+ call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
endif
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
+ call nc_diag_metadata_to_single("Errinv_Input",errinv_input )
+ call nc_diag_metadata_to_single("Errinv_Adjust",errinv_adjst )
+ call nc_diag_metadata_to_single("Errinv_Final",errinv_final )
- call nc_diag_metadata("Observation", sngl(pob) )
- call nc_diag_metadata("Obs_Minus_Forecast_adjusted", sngl(pob-pges) )
- call nc_diag_metadata("Obs_Minus_Forecast_unadjusted", sngl(pob-pgesorig))
+ call nc_diag_metadata_to_single("Observation",pob )
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_adjusted",pob,pges,'-')
+ call nc_diag_metadata_to_single("Obs_Minus_Forecast_unadjusted",pob,pgesorig,'-')
if (lobsdiagsave) then
do jj=1,miter
diff --git a/src/gsi/setuptd2m.f90 b/src/gsi/setuptd2m.f90
index 9e54171bd7..30f6a8b6e3 100644
--- a/src/gsi/setuptd2m.f90
+++ b/src/gsi/setuptd2m.f90
@@ -191,7 +191,7 @@ subroutine setuptd2m(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diag
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
dup=one
diff --git a/src/gsi/setupuwnd10m.f90 b/src/gsi/setupuwnd10m.f90
index 4552a7e81a..dcf7914020 100644
--- a/src/gsi/setupuwnd10m.f90
+++ b/src/gsi/setupuwnd10m.f90
@@ -229,7 +229,7 @@ subroutine setupuwnd10m(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_d
goverrd=grav/rd
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! Check for missing data
@@ -428,7 +428,7 @@ subroutine setupuwnd10m(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_d
lowlevelsat=itype==242.or.itype==243.or.itype==245.or.itype==246.or. &
itype==247.or.itype==250.or.itype==251.or.itype==252.or. &
itype==253.or.itype==254.or.itype==257.or.itype==258.or. &
- itype==259
+ itype==259.or.itype==241
if (lowlevelsat .and. twodvar_regional) then
call windfactor(presw,factw)
data(iuob,i)=factw*data(iuob,i)
diff --git a/src/gsi/setupvis.f90 b/src/gsi/setupvis.f90
index e395c4f7fb..6b514fd47b 100644
--- a/src/gsi/setupvis.f90
+++ b/src/gsi/setupvis.f90
@@ -204,7 +204,7 @@ subroutine setupvis(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diags
isprvd=18 ! index of subprovider
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! Check for missing data !need obs value and error
diff --git a/src/gsi/setupvwnd10m.f90 b/src/gsi/setupvwnd10m.f90
index 0c601e716b..d3c7e573ed 100644
--- a/src/gsi/setupvwnd10m.f90
+++ b/src/gsi/setupvwnd10m.f90
@@ -229,7 +229,7 @@ subroutine setupvwnd10m(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_d
goverrd=grav/rd
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! Check for missing data
@@ -428,7 +428,7 @@ subroutine setupvwnd10m(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_d
lowlevelsat=itype==242.or.itype==243.or.itype==245.or.itype==246.or. &
itype==247.or.itype==250.or.itype==251.or.itype==252.or. &
itype==253.or.itype==254.or.itype==257.or.itype==258.or. &
- itype==259
+ itype==259.or.itype==241
if (lowlevelsat .and. twodvar_regional) then
call windfactor(presw,factw)
data(iuob,i)=factw*data(iuob,i)
diff --git a/src/gsi/setupw.f90 b/src/gsi/setupw.f90
index 174b6e695e..34c62e85dc 100644
--- a/src/gsi/setupw.f90
+++ b/src/gsi/setupw.f90
@@ -44,7 +44,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
use obsmod, only: l_obsprvdiag
use obsmod, only: neutral_stability_windfact_2dvar,use_similarity_2dvar
use nc_diag_write_mod, only: nc_diag_init, nc_diag_header, nc_diag_metadata, &
- nc_diag_write, nc_diag_data2d
+ nc_diag_write, nc_diag_data2d, nc_diag_metadata_to_single
use nc_diag_read_mod, only: nc_diag_read_init, nc_diag_read_get_dim, nc_diag_read_close
use gsi_4dvar, only: nobs_bins,hr_obsbin,min_offset
use qcmod, only: npres_print,ptop,pbot,dfact,dfact1,qc_satwnds,njqc,vqc
@@ -55,8 +55,10 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
use guess_grids, only: nfldsig,hrdifsig,geop_hgtl,sfcmod_gfs
use guess_grids, only: tropprs,sfcmod_mm5
use guess_grids, only: ges_lnprsl,comp_fact10,pbl_height
+ use guess_grids, only: ges_tsen
+ use guess_grids, only: ges_prsi
use constants, only: zero,half,one,tiny_r_kind,two, &
- three,rd,grav,four,five,huge_single,r1000,wgtlim,r10,r400
+ three,rd,grav,four,five,huge_single,r100,r1000,wgtlim,r10,r400
use constants, only: grav_ratio,flattening,deg2rad, &
grav_equator,somigliana,semi_major_axis,eccentricity
use jfunc, only: jiter,last,jiterstart,miter
@@ -219,7 +221,6 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
! level; they are now loaded by
! aircraftinfo.
! 2020-05-04 wu - no rotate_wind for fv3_regional
-! 2021-07-25 Genkova - write AMVQ in diagnostic files
! 2021-10-xx pondeca/morris/zhao - added observation provider/subprovider
! information in diagonostic file, which is used
! in offline observation quality control program (AutoObsQC)
@@ -265,6 +266,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
real(r_kind) presw,factw,dpres,ugesin,vgesin,rwgt,dpressave
real(r_kind) sfcchk,prsln2,error,dtime,dlon,dlat,r0_001,rsig,thirty,rsigp
real(r_kind) ratio_errors,goverrd,spdges,spdob,ten,psges,zsges
+ real(r_kind) ratio_errors1, in_error_1, in_error_2 !ADC
real(r_kind) slat,sin2,termg,termr,termrg,pobl,uob,vob
real(r_kind) uob_reg,vob_reg,uob_e,vob_e,dlon_e,uges_e,vges_e,dudiff_e,dvdiff_e
real(r_kind) dz,zob,z1,z2,p1,p2,dz21,dlnp21,spdb,dstn
@@ -272,13 +274,28 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
real(r_kind) err_input,err_adjst,err_final,skint,sfcr
real(r_kind) dudiff_opp, dvdiff_opp, vecdiff, vecdiff_opp
real(r_kind) dudiff_opp_rs, dvdiff_opp_rs, vecdiff_rs, vecdiff_opp_rs
- real(r_kind) oscat_vec,ascat_vec,rapidscat_vec
+ real(r_kind) oscat_vec,rapidscat_vec
+! real(r_kind) ascat_vec
real(r_kind),dimension(nele,nobs):: data
real(r_kind),dimension(nobs):: dup
real(r_kind),dimension(nsig)::prsltmp,tges,zges
+ real(r_kind),dimension(nsig)::zges_read !emily: from geop_heigtl
+ real(r_kind),dimension(nsig)::zges_geometric !emily: calculated from zges_read
real(r_kind) wdirob,wdirgesin,wdirdiffmax
real(r_kind),dimension(34)::ptabluv
real(r_single),allocatable,dimension(:,:)::rdiagbuf
+ real(r_kind),dimension(nsig):: prsltmp2
+ real(r_kind),dimension(nsig+1):: prsitmp
+ real(r_kind),dimension(nsig):: ttmp,qtmp,utmp,vtmp,hsges
+ ! GSI profiles are stored with bottom up index; output the profiles
+ ! with top down index
+ real(r_kind),dimension(nsig):: ttmp_reverse,tvtmp_reverse,qtmp_reverse,utmp_reverse,vtmp_reverse
+ real(r_kind),dimension(nsig):: hsges_reverse, zges_reverse,prsltmp2_reverse
+ real(r_kind),dimension(nsig):: zges_read_reverse, zges_geometric_reverse
+ real(r_kind),dimension(nsig+1):: prsitmp_reverse
+ real(r_kind) psges2
+ !<< JEDI
+
integer(i_kind) i,nchar,nreal,k,j,l,ii,itype,ijb
! Variables needed for new polar winds QC based on Log Normalized Vector Departure (LNVD)
@@ -293,7 +310,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
integer(i_kind) ihgt,ier2,iuse,ilate,ilone
integer(i_kind) izz,iprvd,isprvd
integer(i_kind) idomsfc,isfcr,iskint,iff10
- integer(i_kind) ibb,ikk,ihil,idddd,iamvq
+ integer(i_kind) ibb,ikk,ihil,idddd,iamvq,kk
integer(i_kind) num_bad_ikx,iprev_station
@@ -334,6 +351,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
real(r_kind),allocatable,dimension(:,:,: ) :: ges_ps
real(r_kind),allocatable,dimension(:,:,: ) :: ges_z
+ real(r_kind),allocatable,dimension(:,:,:,:) :: ges_q
real(r_kind),allocatable,dimension(:,:,:,:) :: ges_u
real(r_kind),allocatable,dimension(:,:,:,:) :: ges_v
real(r_kind),allocatable,dimension(:,:,:,:) :: ges_tv
@@ -385,8 +403,8 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
ijb=25 ! index of non linear qc parameter
ihil=26 ! index of hilbert curve weight
iamvq=27 ! index of AMVQ
- iptrbu=28 ! index of u perturbation
- iptrbv=29 ! index of v perturbation
+ iptrbu=35 ! index of u perturbation
+ iptrbv=36 ! index of v perturbation
mm1=mype+1
scale=one
@@ -402,7 +420,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
if(conv_diagsave)then
ii=0
nchar=1
- ioff0=26
+ ioff0=25
nreal=ioff0
if (lobsdiagsave) nreal=nreal+7*miter+2
if (twodvar_regional .or. l_obsprvdiag) then
@@ -421,14 +439,8 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
if (netcdf_diag) call init_netcdf_diag_
end if
- num_bad_ikx=0
do i=1,nobs
- muse(i)=nint(data(iuse,i)) <= jiter
- ikx=nint(data(ikxx,i))
- if(ikx < 1 .or. ikx > nconvtype) then
- num_bad_ikx=num_bad_ikx+1
- if(num_bad_ikx<=10) write(6,*)' in setupw ',ikx,i,nconvtype,mype
- end if
+ muse(i)=nint(data(iuse,i)) <= jiter .and. nint(data(iqc,i)) < 8
end do
! If HD raobs available move prepbufr version to monitor
if(nhduv > 0)then
@@ -585,6 +597,23 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
call tintrp2a1(ges_lnprsl,prsltmp,dlat,dlon,dtime,hrdifsig,&
nsig,mype,nfldsig)
+! GEOVALS for UFO eval
+ psges2 = psges ! keep in cb
+ prsltmp2 = exp(prsltmp)
+ call tintrp2a1(ges_prsi,prsitmp,dlat,dlon,dtime,hrdifsig,&
+ nsig+1,mype,nfldsig)
+ call tintrp2a1(ges_tsen,ttmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(ges_q,qtmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(ges_u,utmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(ges_v,vtmp,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+ call tintrp2a1(geop_hgtl,hsges,dlat,dlon,dtime,hrdifsig,&
+ nsig,mype,nfldsig)
+
+! END GEOVALS
! Type 221=pibal winds contain a mixture of wind observations reported
! by pressure and others by height. Those levels only reported by
! pressure have a missing value (ie, large) value for the reported
@@ -685,7 +714,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
hrdifsig,mype,nfldsig)
iz = max(1, min( int(dpres), nsig))
- delz = max(zero, min(dpres - float(iz), one))
+ delz = max(zero, min(dpres - real(iz,r_kind), one))
if (save_jacobian) then
@@ -813,7 +842,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
hrdifsig,mype,nfldsig)
iz = max(1, min( int(dpres), nsig))
- delz = max(zero, min(dpres - float(iz), one))
+ delz = max(zero, min(dpres - real(iz,r_kind), one))
if (save_jacobian) then
u_ind = getindex(svars3d, 'u')
@@ -880,12 +909,14 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
if(rhgh/=zero) awork(3) = awork(3) + one
end if
ratio_errors=error/(data(ier,i)+drpx+1.0e6_r_kind*rhgh+four*rlow)
-
+ ratio_errors1=ratio_errors ! ADC
+ in_error_1=error ! ADC
+ in_error_2=data(ier,i) ! ADC
! Compute innovations
lowlevelsat=itype==242.or.itype==243.or.itype==245.or.itype==246.or. &
itype==247.or.itype==250.or.itype==251.or.itype==252.or. &
itype==253.or.itype==254.or.itype==257.or.itype==258.or. &
- itype==259
+ itype==259.or.itype==241
if (lowlevelsat .and. twodvar_regional) then
call windfactor(presw,factw)
data(iuob,i)=factw*data(iuob,i)
@@ -902,8 +933,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
if (itype==236) then
magomb=sqrt(dudiff*dudiff+dvdiff*dvdiff)
ratio_errors=error/((uv_doe_a_236*magomb+uv_doe_b_236)+drpx+1.0e6_r_kind*rhgh+four*rlow)
- endif
- if (itype==237) then
+ else if (itype==237) then
magomb=sqrt(dudiff*dudiff+dvdiff*dvdiff)
ratio_errors=error/((uv_doe_a_237*magomb+uv_doe_b_237)+drpx+1.0e6_r_kind*rhgh+four*rlow)
endif
@@ -947,106 +977,102 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
if (itype >=240 .and. itype <=260) then
call intrp2a11(tropprs,trop5,dlat,dlon,mype)
if(presw < trop5-r50) error=zero ! tropopose check for all satellite winds
- endif
-
- if(itype >=240 .and. itype <=260) then
if(i_gsdqc==2) then
prsfc = r10*psges
if( prsfc-presw < 100.0_r_kind) error =zero ! add check for obs within 100 hPa of sfc
else
if( presw >950.0_r_kind) error =zero ! screen data beloww 950mb
endif
- endif
- if(itype ==242 .or. itype ==243 ) then ! visible winds from JMA and EUMETSAT
- if(presw <700.0_r_kind) error=zero ! no visible winds above 700mb
- endif
- if(itype ==245 ) then
- if( presw >399.0_r_kind .and. presw <801.0_r_kind) then !GOES IR winds
- error=zero ! no data between 400-800mb
- endif
- endif
- if(itype == 252 .and. presw >499.0_r_kind .and. presw <801.0_r_kind) then ! JMA IR winds
- error=zero
- endif
- if(itype == 253 ) then
- if(presw >401.0_r_kind .and. presw <801.0_r_kind) then ! EUMET IR winds
- error=zero
- endif
- endif
- if( itype == 246 .or. itype == 250 .or. itype == 254 ) then ! water vapor cloud top
- if(presw >399.0_r_kind) error=zero
- endif
- if(itype ==257 .and. presw <249.0_r_kind) error=zero
- if(itype ==258 .and. presw >600.0_r_kind) error=zero
- if(itype ==259 .and. presw >600.0_r_kind) error=zero
- if(itype ==259 .and. presw <249.0_r_kind) error=zero
- endif ! qc_satwnds
-
-! QC GOES CAWV - some checks above as well
- if (itype==247) then
- prsfc = r10*psges ! surface pressure in hPa
-
-! Compute observed and guess wind speeds (m/s).
- spdges = sqrt(ugesin* ugesin +vgesin* vgesin )
-
-! Set and compute GOES CAWV specific departure parameters
- LNVD_wspd = spdob
- LNVD_omb = sqrt(dudiff*dudiff + dvdiff*dvdiff)
- LNVD_ratio = LNVD_omb / log(LNVD_wspd)
- LNVD_threshold = 3.0_r_kind
- if( .not. wrf_nmm_regional) then ! LNVD check not use for CAWV winds in HWRF
- if(LNVD_ratio >= LNVD_threshold .or. & ! LNVD check
- (presw > prsfc-110.0_r_kind .and. isli /= 0))then ! near surface check 110 ~1km
- error = zero
- endif
- endif
-! check for direction departure gt 50 deg
- wdirdiffmax=50._r_kind
- call getwdir(uob,vob,wdirob)
- call getwdir(ugesin,vgesin,wdirgesin)
- if ( min(abs(wdirob-wdirgesin),abs(wdirob-wdirgesin+r360), &
- abs(wdirob-wdirgesin-r360)) > wdirdiffmax ) then
- error = zero
- endif
- endif
+ if(itype == 241 ) then
+ if( presw >399.0_r_kind .and. presw <601.0_r_kind) then !CIMISS(enhanced AMV) winds
+ error=zero ! no data between400-600mb
+ endif
+ else if(itype ==242 .or. itype ==243 ) then ! visible winds from JMA and EUMETSAT
+ if(presw <700.0_r_kind) error=zero ! no visible winds above 700mb
+ else if(itype ==245 ) then
+ if( presw >399.0_r_kind .and. presw <801.0_r_kind) then !GOES IR winds
+ error=zero ! no data between 400-800mb
+ endif
+ else if(itype == 252 )then
+ if( presw >499.0_r_kind .and. presw <801.0_r_kind) then ! JMA IR winds
+ error=zero
+ end if
+ else if(itype == 253 ) then
+ if(presw >401.0_r_kind .and. presw <801.0_r_kind) then ! EUMET IR winds
+ error=zero
+ endif
+ else if( itype == 246 .or. itype == 250 .or. itype == 254 ) then ! water vapor cloud top
+ if(presw >399.0_r_kind) error=zero
+
+! QC GOES CAWV - some checks above as well
+ else if (itype==247) then
+ prsfc = r10*psges ! surface pressure in hPa
+
+! Compute observed and guess wind speeds (m/s).
+ spdges = sqrt(ugesin* ugesin +vgesin* vgesin )
+
+! Set and compute GOES CAWV specific departure parameters
+ LNVD_wspd = spdob
+ LNVD_omb = sqrt(dudiff*dudiff + dvdiff*dvdiff)
+ LNVD_ratio = LNVD_omb / log(LNVD_wspd)
+ LNVD_threshold = 3.0_r_kind
+ if( .not. wrf_nmm_regional) then ! LNVD check not use for CAWV winds in HWRF
+ if(LNVD_ratio >= LNVD_threshold .or. & ! LNVD check
+ (presw > prsfc-110.0_r_kind .and. isli /= 0))then ! near surface check 110 ~1km
+ error = zero
+ endif
+ endif
+! check for direction departure gt 50 deg
+ wdirdiffmax=50._r_kind
+ call getwdir(uob,vob,wdirob)
+ call getwdir(ugesin,vgesin,wdirgesin)
+ if ( min(abs(wdirob-wdirgesin),abs(wdirob-wdirgesin+r360), &
+ abs(wdirob-wdirgesin-r360)) > wdirdiffmax ) then
+ error = zero
+ endif
! QC MODIS winds
- if (itype==257 .or. itype==258 .or. itype==259 .or. itype ==260) then
-! Get guess values of tropopause pressure and sea/land/ice
-! mask at observation location
- prsfc = r10*prsfc ! surface pressure in hPa
-
-! Compute observed and guess wind speeds (m/s).
- spdges = sqrt(ugesin* ugesin +vgesin* vgesin )
+ else if (itype==257 .or. itype==258 .or. itype==259 .or. itype ==260) then
+ if(itype ==257 .and. presw <249.0_r_kind) error=zero
+ if(itype ==258 .and. presw >600.0_r_kind) error=zero
+ if(itype ==259 .and. presw >600.0_r_kind) error=zero
+ if(itype ==259 .and. presw <249.0_r_kind) error=zero
+! Get guess values of tropopause pressure and sea/land/ice
+! mask at observation location
+ prsfc = r10*prsfc ! surface pressure in hPa
+
+! Compute observed and guess wind speeds (m/s).
+ spdges = sqrt(ugesin* ugesin +vgesin* vgesin )
-! Set and computes modis specific qc parameters
- LNVD_wspd = spdob
- LNVD_omb = sqrt(dudiff*dudiff + dvdiff*dvdiff)
- LNVD_ratio = LNVD_omb / log(LNVD_wspd)
- LNVD_threshold = 3.0_r_kind
- if(LNVD_ratio >= LNVD_threshold .or. & ! LNVD check
- (presw > prsfc-r200 .and. isli /= 0))then ! near surface check
- error = zero
- endif
- endif ! ???
-
-! QC AVHRR winds
- if (itype==244) then
-! Get guess values of tropopause pressure and sea/land/ice
-! mask at observation location
- prsfc = r10*prsfc ! surface pressure in hPa
-
-! Set and computes modis specific qc parameters
- LNVD_wspd = spdob
- LNVD_omb = sqrt(dudiff*dudiff + dvdiff*dvdiff)
- LNVD_ratio = LNVD_omb / log(LNVD_wspd)
- LNVD_threshold = 3.0_r_kind
-
- if(LNVD_ratio >= LNVD_threshold .or. & ! LNVD check
- (presw > prsfc-r200 .and. isli /= 0))then ! near surface check
- error = zero
+! Set and computes modis specific qc parameters
+ LNVD_wspd = spdob
+ LNVD_omb = sqrt(dudiff*dudiff + dvdiff*dvdiff)
+ LNVD_ratio = LNVD_omb / log(LNVD_wspd)
+ LNVD_threshold = 3.0_r_kind
+ if(LNVD_ratio >= LNVD_threshold .or. & ! LNVD check
+ (presw > prsfc-r200 .and. isli /= 0))then ! near surface check
+ error = zero
+ endif
+
+! QC AVHRR winds
+ else if (itype==244) then
+! Get guess values of tropopause pressure and sea/land/ice
+! mask at observation location
+ prsfc = r10*prsfc ! surface pressure in hPa
+
+! Set and computes modis specific qc parameters
+ LNVD_wspd = spdob
+ LNVD_omb = sqrt(dudiff*dudiff + dvdiff*dvdiff)
+ LNVD_ratio = LNVD_omb / log(LNVD_wspd)
+ LNVD_threshold = 3.0_r_kind
+
+ if(LNVD_ratio >= LNVD_threshold .or. & ! LNVD check
+ (presw > prsfc-r200 .and. isli /= 0))then ! near surface check
+ error = zero
+ endif
+ endif ! end if all satellite winds
endif
- endif ! end if all satellite winds
+ endif
! QC WindSAT winds
@@ -1058,10 +1084,9 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
abs(dvdiff) > qcv ) then ! v component check
error = zero
endif
- endif
! QC ASCAT winds
- if (itype==290) then
+ else if (itype==290) then
qcu = five
qcv = five
! Compute innovations for opposite vectors
@@ -1069,7 +1094,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
dvdiff_opp = -vob - vgesin
vecdiff = sqrt(dudiff**2 + dvdiff**2)
vecdiff_opp = sqrt(dudiff_opp**2 + dvdiff_opp**2)
- ascat_vec = sqrt((dudiff**2 + dvdiff**2)/spdob**2)
+! ascat_vec = sqrt((dudiff**2 + dvdiff**2)/spdob**2)
if ( abs(dudiff) > qcu .or. & ! u component check
abs(dvdiff) > qcv .or. & ! v component check
@@ -1077,10 +1102,9 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
error = zero
endif
- endif
! QC RAPIDSCAT winds
- if (itype==296) then
+ else if (itype==296) then
qcu = five
qcv = five
! Compute innovations for opposite vectors
@@ -1094,10 +1118,9 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
vecdiff_rs > vecdiff_opp_rs ) then ! ambiguity check
error = zero
endif
- endif
! QC OSCAT winds
- if (itype==291) then
+ else if (itype==291) then
qcu = r6
qcv = r6
oscat_vec = sqrt((dudiff**2 + dvdiff**2)/spdob**2)
@@ -1154,7 +1177,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
if(itype ==244) then ! AVHRR, use same as MODIS
qcgross=r0_7*cgross(ikx)
endif
- if( itype == 245 .or. itype ==246) then
+ if( itype == 245 .or. itype ==246 .or. itype ==241) then
if(presw <400.0_r_kind .and. presw >300.0_r_kind ) qcgross=r0_7*cgross(ikx)
endif
if(itype == 253 .or. itype ==254) then
@@ -1254,7 +1277,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
call vqc_setup(vals,ratio_errors,error,cvar,&
cg_t,ibb,ikk,var_jb,rat_err2v,wgt,valqcv)
rwgt = rwgt+0.5_r_kind*wgt/wgtlim
- valqc=valqcu+valqcv
+ valqc=half*(valqcu+valqcv)
! Accumulate statistics for obs belonging to this task
if (muse(i)) then
@@ -1275,7 +1298,9 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
nn=1
if (.not. muse(i)) then
nn=2
- if(ratio_errors*error >=tiny_r_kind)nn=3
+ if(error*ratio_errors >= tiny_r_kind)nn=3
+! if((data(iqc,i) >= 8 .and. data(iqc,i) <= 10) .or. &
+! error*ratio_errors >= tiny_r_kind)nn=3
end if
do k = 1,npres_print
if(presw >ptop(k) .and. presw<=pbot(k))then
@@ -1333,10 +1358,9 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
my_head%ib=ibeta(ikx)
my_head%ik=ikapa(ikx)
my_head%luse=luse(i)
-! if( i==3) print *,'SETUPW',my_head%ures,my_head%vres,my_head%err2
- if (luse_obsdiag) then
- endif ! (luse_obsdiag)
+! if( i==3) print *,'SETUPW',my_head%ures,my_head%vres,my_head%err2
+
if(oberror_tune) then
my_head%upertb=data(iptrbu,i)/error/ratio_errors
@@ -1361,6 +1385,7 @@ subroutine setupw(obsLL,odiagLL,lunin,mype,bwork,awork,nele,nobs,is,conv_diagsav
endif
endif
+
if (luse_obsdiag) then
call obsdiagNode_assert(my_diagu, my_head%idv,my_head%iob,my_head%ich0+1_i_kind,myname,"my_diagu:my_head")
call obsdiagNode_assert(my_diagv, my_head%idv,my_head%iob,my_head%ich0+2_i_kind,myname,"my_diagv:my_head")
@@ -1571,6 +1596,24 @@ subroutine init_vars_
write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
call stop2(999)
endif
+! get q ...
+ varname='q'
+ call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank3,istatus)
+ if (istatus==0) then
+ if(allocated(ges_q))then
+ write(6,*) trim(myname), ': ', trim(varname), ' already incorrectly alloc '
+ call stop2(999)
+ endif
+ allocate(ges_q(size(rank3,1),size(rank3,2),size(rank3,3),nfldsig))
+ ges_q(:,:,:,1)=rank3
+ do ifld=2,nfldsig
+ call gsi_bundlegetpointer(gsi_metguess_bundle(ifld),trim(varname),rank3,istatus)
+ ges_q(:,:,:,ifld)=rank3
+ enddo
+ else
+ write(6,*) trim(myname),': ', trim(varname), ' not found in met bundle, ier= ',istatus
+ call stop2(999)
+ endif
! get u ...
varname='u'
call gsi_bundlegetpointer(gsi_metguess_bundle(1),trim(varname),rank3,istatus)
@@ -1725,7 +1768,6 @@ subroutine contents_binary_diag_(udiag,vdiag)
rdiagbuf(23,ii) = factw ! 10m wind reduction factor
rdiagbuf(24,ii) = 1.e+10_r_single ! u spread (filled in by EnKF)
rdiagbuf(25,ii) = 1.e+10_r_single ! v spread (filled in by EnKF)
- rdiagbuf(26,ii) = data(iamvq,i) ! AMVQ mitigation flag for AMVs;only for GOES17,LHP issue
ioff=ioff0
if (lobsdiagsave) then
@@ -1791,39 +1833,47 @@ subroutine contents_netcdf_diag_(udiag,vdiag)
call nc_diag_metadata("Observation_Class", obsclass )
call nc_diag_metadata("Observation_Type", ictype(ikx) )
call nc_diag_metadata("Observation_Subtype", icsubtype(ikx) )
- call nc_diag_metadata("Latitude", sngl(data(ilate,i)) )
- call nc_diag_metadata("Longitude", sngl(data(ilone,i)) )
- call nc_diag_metadata("Station_Elevation", sngl(data(ielev,i)) )
- call nc_diag_metadata("Pressure", sngl(presw) )
- call nc_diag_metadata("Height", sngl(data(ihgt,i)) )
- call nc_diag_metadata("Time", sngl(dtime-time_offset))
- call nc_diag_metadata("Prep_QC_Mark", sngl(data(iqc,i)) )
+ call nc_diag_metadata_to_single("Latitude",data(ilate,i) )
+ call nc_diag_metadata_to_single("Longitude",data(ilone,i) )
+ call nc_diag_metadata_to_single("Station_Elevation",data(ielev,i) )
+ call nc_diag_metadata_to_single("Pressure",presw )
+ call nc_diag_metadata_to_single("Height",data(ihgt,i) )
+ call nc_diag_metadata_to_single("Time",dtime,time_offset,'-')
+ call nc_diag_metadata_to_single("Prep_QC_Mark",data(iqc,i) )
! call nc_diag_metadata("Setup_QC_Mark", rmiss_single )
- call nc_diag_metadata("Setup_QC_Mark", sngl(bmiss) )
- call nc_diag_metadata("Nonlinear_QC_Var_Jb", sngl(var_jb) )
- call nc_diag_metadata("Prep_Use_Flag", sngl(data(iuse,i)) )
+ call nc_diag_metadata_to_single("Setup_QC_Mark",bmiss )
+ call nc_diag_metadata_to_single("Nonlinear_QC_Var_Jb",var_jb )
+ call nc_diag_metadata_to_single("Prep_Use_Flag",data(iuse,i) )
if(muse(i)) then
- call nc_diag_metadata("Analysis_Use_Flag", sngl(one) )
+ call nc_diag_metadata_to_single("Analysis_Use_Flag", one )
else
- call nc_diag_metadata("Analysis_Use_Flag", sngl(-one) )
+ call nc_diag_metadata_to_single("Analysis_Use_Flag", -one )
endif
- call nc_diag_metadata("Nonlinear_QC_Rel_Wgt", sngl(rwgt) )
- call nc_diag_metadata("Errinv_Input", sngl(errinv_input) )
- call nc_diag_metadata("Errinv_Adjust", sngl(errinv_adjst) )
- call nc_diag_metadata("Errinv_Final", sngl(errinv_final) )
+ !call nc_diag_metadata_to_single("drpx",drpx ) ! ADC
+ !call nc_diag_metadata_to_single("rhgh",rhgh ) ! ADC
+ !call nc_diag_metadata_to_single("rlow",rlow ) ! ADC
+ !call nc_diag_metadata_to_single("in_error_1",in_error_1 ) ! ADC
+ !call nc_diag_metadata_to_single("in_error_2",in_error_2 ) ! ADC
+ !call nc_diag_metadata_to_single("ratio_errors",ratio_errors1) ! ADC
+
+
+ call nc_diag_metadata_to_single("Nonlinear_QC_Rel_Wgt",rwgt)
+ call nc_diag_metadata_to_single("Errinv_Input",errinv_input)
+ call nc_diag_metadata_to_single("Errinv_Adjust",errinv_adjst)
+ call nc_diag_metadata_to_single("Errinv_Final",errinv_final)
! AMVQ Mitigated winds
- call nc_diag_metadata("Mitigation_flag_AMVQ", sngl(data(iamvq,i)) )
- call nc_diag_metadata("Wind_Reduction_Factor_at_10m", sngl(factw) )
+ call nc_diag_metadata_to_single("Mitigation_flag_AMVQ",data(iamvq,i) )
+ call nc_diag_metadata_to_single("Wind_Reduction_Factor_at_10m",factw )
if (.not. regional .or. fv3_regional) then
- call nc_diag_metadata("u_Observation", sngl(data(iuob,i)) )
- call nc_diag_metadata("u_Obs_Minus_Forecast_adjusted", sngl(dudiff) )
- call nc_diag_metadata("u_Obs_Minus_Forecast_unadjusted", sngl(uob-ugesin) )
+ call nc_diag_metadata_to_single("u_Observation",data(iuob,i) )
+ call nc_diag_metadata_to_single("u_Obs_Minus_Forecast_adjusted",dudiff )
+ call nc_diag_metadata_to_single("u_Obs_Minus_Forecast_unadjusted",uob,ugesin,'-')
- call nc_diag_metadata("v_Observation", sngl(data(ivob,i)) )
- call nc_diag_metadata("v_Obs_Minus_Forecast_adjusted", sngl(dvdiff) )
- call nc_diag_metadata("v_Obs_Minus_Forecast_unadjusted", sngl(vob-vgesin) )
+ call nc_diag_metadata_to_single("v_Observation",data(ivob,i) )
+ call nc_diag_metadata_to_single("v_Obs_Minus_Forecast_adjusted",dvdiff )
+ call nc_diag_metadata_to_single("v_Obs_Minus_Forecast_unadjusted",vob,vgesin,'-')
else ! (if regional)
! replace positions 17-22 with earth relative wind component information
@@ -1834,13 +1884,13 @@ subroutine contents_netcdf_diag_(udiag,vdiag)
call rotate_wind_xy2ll(ugesin,vgesin,uges_e,vges_e,dlon_e,dlon,dlat)
call rotate_wind_xy2ll(dudiff,dvdiff,dudiff_e,dvdiff_e,dlon_e,dlon,dlat)
- call nc_diag_metadata("u_Observation", sngl(uob_e) )
- call nc_diag_metadata("u_Obs_Minus_Forecast_adjusted", sngl(dudiff_e) )
- call nc_diag_metadata("u_Obs_Minus_Forecast_unadjusted", sngl(uob_e-uges_e) )
+ call nc_diag_metadata_to_single("u_Observation",uob_e )
+ call nc_diag_metadata_to_single("u_Obs_Minus_Forecast_adjusted",dudiff_e )
+ call nc_diag_metadata_to_single("u_Obs_Minus_Forecast_unadjusted",uob_e,uges_e,'-')
- call nc_diag_metadata("v_Observation", sngl(vob_e) )
- call nc_diag_metadata("v_Obs_Minus_Forecast_adjusted", sngl(dvdiff_e) )
- call nc_diag_metadata("v_Obs_Minus_Forecast_unadjusted", sngl(vob_e-vges_e) )
+ call nc_diag_metadata_to_single("v_Observation",vob_e )
+ call nc_diag_metadata_to_single("v_Obs_Minus_Forecast_adjusted",dvdiff_e )
+ call nc_diag_metadata_to_single("v_Obs_Minus_Forecast_unadjusted",vob_e,vges_e,'-')
endif
if (lobsdiagsave) then
@@ -1880,12 +1930,81 @@ subroutine contents_netcdf_diag_(udiag,vdiag)
call nc_diag_data2d("v_Observation_Operator_Jacobian_val", real(dhx_dx_v%val,r_single))
endif
+ ! GEOVALS
+ !>>emily
+ do k = 1, nsig
+ kk = nsig-k+1
+ utmp_reverse(kk) = utmp(k)
+ vtmp_reverse(kk) = vtmp(k)
+ ttmp_reverse(kk) = ttmp(k)
+ tvtmp_reverse(kk) = tges(k) !emily
+ qtmp_reverse(kk) = qtmp(k)
+ hsges_reverse(kk) = hsges(k)
+ zges_read_reverse(kk)= zges_read(k)
+ zges_geometric_reverse(kk)= zges_geometric(k)
+ zges_reverse(kk) = zges(k)
+ prsltmp2_reverse(kk) = prsltmp2(k)
+ enddo
+ do k = 1, nsig+1
+ kk = (nsig+1)-k+1
+ prsitmp_reverse(kk) = prsitmp(k)
+ enddo
+
+ call nc_diag_data2d("atmosphere_pressure_coordinate", sngl(prsltmp2_reverse*r1000))
+ call nc_diag_data2d("atmosphere_pressure_coordinate_interface", sngl(prsitmp_reverse*r1000))
+ call nc_diag_data2d("air_temperature", sngl(ttmp_reverse))
+ call nc_diag_data2d("virtual_temperature", sngl(tvtmp_reverse)) !emily
+ call nc_diag_data2d("specific_humidity", sngl(qtmp_reverse))
+ call nc_diag_data2d("eastward_wind", sngl(utmp_reverse))
+ call nc_diag_data2d("northward_wind", sngl(vtmp_reverse))
+! call nc_diag_data2d("geopotential_height", sngl(hsges_reverse) ) !orig
+ call nc_diag_data2d("geopotential_height", sngl(zges_read_reverse) ) !emily
+ call nc_diag_data2d("geometric_height", sngl(zges_geometric_reverse) ) !emily
+ !<= float(n-1)*binwidth .and. wdir < float(n)*binwidth ) then
+ if ( wdir >= real(n-1,r_kind)*binwidth .and. wdir < real(n,r_kind)*binwidth ) then
ibin=n
exit
endif
diff --git a/src/gsi/smoothzrf.f90 b/src/gsi/smoothzrf.f90
index 06e877ee68..dae656ca1b 100644
--- a/src/gsi/smoothzrf.f90
+++ b/src/gsi/smoothzrf.f90
@@ -81,7 +81,7 @@ subroutine frfhvo(p1,iv)
do k=1,lat2
l=int(rllat1(k,j))
l2=min0(l+1,llmax)
- dl2(k,j)=rllat1(k,j)-float(l)
+ dl2(k,j)=rllat1(k,j)-real(l,r_kind)
dl1(k,j)=one-dl2(k,j)
end do
end do
diff --git a/src/gsi/ssmis_spatial_average_mod.f90 b/src/gsi/ssmis_spatial_average_mod.f90
index 24ac91d3f1..30b69c6223 100644
--- a/src/gsi/ssmis_spatial_average_mod.f90
+++ b/src/gsi/ssmis_spatial_average_mod.f90
@@ -682,26 +682,15 @@ SUBROUTINE SSMIS_Spatial_Average(BufrSat, Method, Num_Obs, NChanl, &
! Define grid box by channel -
! Ch 1-2: 1 scan direction, 1 track direction
! Ch 3-13: 3 scan direction, 3 track direction
- if ((ic == 1) .or. (ic == 2)) then
- ns1 = iscan
- ns2 = iscan
- if (ns1 < 1) ns1=1
- if (ns2 > max_scan) ns2=max_scan
- np1 = ifov
- np2 = ifov
- if (np1 < 1) np1=1
- if (np2 > max_fov_gmi) np2=max_fov_gmi
- else if ((ic > 2) .and. (ic < 14)) then
- ns1 = iscan-1
- ns2 = iscan+1
- if (ns1 < 1) ns1=1
- if (ns2 > max_scan) ns2=max_scan
- np1 = ifov-1
- np2 = ifov+1
- if (np1 < 1) np1=1
- if (np2 > max_fov_gmi) np2=max_fov_gmi
- endif
+ ns1 = iscan-4
+ ns2 = iscan+4
+ if (ns1 < 1) ns1=1
+ if (ns2 > max_scan) ns2=max_scan
+ np1 = ifov-8
+ np2 = ifov+8
+ if (np1 < 1) np1=1
+ if (np2 > max_fov_gmi) np2=max_fov_gmi
xnum = 0.0_r_kind
mta = 0.0_r_kind
if (any(bt_image_orig(np1:np2,ns1:ns2,ic) < btmin .or. &
@@ -716,7 +705,7 @@ SUBROUTINE SSMIS_Spatial_Average(BufrSat, Method, Num_Obs, NChanl, &
lat2 = latitude(ip,is)
lon2 = longitude(ip,is)
dist = distance(lat1,lon1,lat2,lon2)
- if (dist > 50.0_r_kind) cycle gmi_box_x1 ! outside the box
+ if (dist > 20.0_r_kind) cycle gmi_box_x1 ! outside the box
if (gaussian_wgt) then
wgt = exp(-0.5_r_kind*(dist/sigma)*(dist/sigma))
else
@@ -1551,7 +1540,7 @@ SUBROUTINE SFFTCB( X, N, M )
END DO
J = J + K
104 CONTINUE
- XT = 1.0 / FLOAT( N )
+ XT = 1.0 / real( N,r_kind )
DO 99 I = 1, N
X(I) = XT * X(I)
99 CONTINUE
diff --git a/src/gsi/state_vectors.f90 b/src/gsi/state_vectors.f90
index 711043fa57..5a573785e7 100644
--- a/src/gsi/state_vectors.f90
+++ b/src/gsi/state_vectors.f90
@@ -62,7 +62,7 @@ module state_vectors
use GSI_BundleMod, only : GSI_GridCreate
use mpeu_util, only: gettablesize
-use mpeu_util, only: gettable
+use mpeu_util, only: gettable,getindex
implicit none
@@ -83,6 +83,8 @@ module state_vectors
public svars
public levels
public ns2d,ns3d,nsdim
+ public qgpresent,qspresent,qrpresent,qipresent,qlpresent
+ public cldchpresent,lcbaspresent,howvpresent,wspd10mpresent,pblhpresent,vispresent,gustpresent
! State vector definition
! Could contain model state fields plus other fields required
@@ -101,6 +103,8 @@ module state_vectors
character(len=max_varname_length),allocatable,dimension(:) :: svars2d
integer(i_kind) ,allocatable,dimension(:) :: levels
+logical qgpresent,qspresent,qrpresent,qipresent,qlpresent
+logical cldchpresent,lcbaspresent,howvpresent,wspd10mpresent,pblhpresent,vispresent,gustpresent
! ----------------------------------------------------------------------
INTERFACE PRT_STATE_NORMS
@@ -245,6 +249,18 @@ subroutine init_anasv
write(6,*) myname_,': 3D-STATE VARIABLES ', svars3d
write(6,*) myname_,': ALL STATE VARIABLES ', svars
end if
+qgpresent=getindex(svars3d,'qg')>0
+qspresent=getindex(svars3d,'qs')>0
+qrpresent=getindex(svars3d,'qr')>0
+qipresent=getindex(svars3d,'qi')>0
+qlpresent=getindex(svars3d,'ql')>0
+cldchpresent=getindex(svars2d,'cldch')>0
+lcbaspresent=getindex(svars2d,'lcbas')>0
+howvpresent=getindex(svars2d,'howv')>0
+wspd10mpresent=getindex(svars2d,'wspd10m')>0
+pblhpresent=getindex(svars2d,'pblh')>0
+vispresent=getindex(svars2d,'vis')>0
+gustpresent=getindex(svars2d,'gust')>0
end subroutine init_anasv
subroutine final_anasv
@@ -370,7 +386,7 @@ subroutine norms_vars(xst,pmin,pmax,psum,pnum)
! local variables
real(r_kind),allocatable,dimension(:) :: zloc,nloc
real(r_kind),allocatable,dimension(:,:) :: zall,nall
- integer(i_kind) :: i,ii
+ integer(i_kind) :: i
pmin=zero
pmax=zero
@@ -383,59 +399,32 @@ subroutine norms_vars(xst,pmin,pmax,psum,pnum)
zloc=zero
! Independent part of vector
-! Sum
- ii=0
+! Sum,Max,Min and number of points
+!$omp parallel do schedule(static,1) private(i)
do i = 1,ns3d
- ii=ii+1
if(xst%r3(i)%mykind==r_single)then
- zloc(ii)= sum_mask(xst%r3(i)%qr4,ihalo=1)
+ zloc(i)= sum_mask(xst%r3(i)%qr4,ihalo=1)
+ zloc(nvars+i)= minval(xst%r3(i)%qr4)
+ zloc(2*nvars+i)= maxval(xst%r3(i)%qr4)
else
- zloc(ii)= sum_mask(xst%r3(i)%q,ihalo=1)
+ zloc(i)= sum_mask(xst%r3(i)%q,ihalo=1)
+ zloc(nvars+i)= minval(xst%r3(i)%q)
+ zloc(2*nvars+i)= maxval(xst%r3(i)%q)
endif
- nloc(ii) = real((lat2-2)*(lon2-2)*levels(i), r_kind) ! dim of 3d fields
+ nloc(i) = real((lat2-2)*(lon2-2)*levels(i), r_kind) ! dim of 3d fields
enddo
+!$omp parallel do schedule(static,1) private(i)
do i = 1,ns2d
- ii=ii+1
if(xst%r2(i)%mykind==r_single)then
- zloc(ii)= sum_mask(xst%r2(i)%qr4,ihalo=1)
+ zloc(ns3d+i)= sum_mask(xst%r2(i)%qr4,ihalo=1)
+ zloc(nvars+ns3d+i)= minval(xst%r2(i)%qr4)
+ zloc(2*nvars+ns3d+i)= maxval(xst%r2(i)%qr4)
else
- zloc(ii)= sum_mask(xst%r2(i)%q,ihalo=1)
- endif
- nloc(ii) = real((lat2-2)*(lon2-2), r_kind) ! dim of 2d fields
- enddo
-! Min
- do i = 1,ns3d
- ii=ii+1
- if(xst%r3(i)%mykind==r_single)then
- zloc(ii)= minval(xst%r3(i)%qr4)
- else
- zloc(ii)= minval(xst%r3(i)%q)
- endif
- enddo
- do i = 1,ns2d
- ii=ii+1
- if(xst%r2(i)%mykind==r_single)then
- zloc(ii)= minval(xst%r2(i)%qr4)
- else
- zloc(ii)= minval(xst%r2(i)%q)
- endif
- enddo
-! Max
- do i = 1,ns3d
- ii=ii+1
- if(xst%r3(i)%mykind==r_single)then
- zloc(ii)= maxval(xst%r3(i)%qr4)
- else
- zloc(ii)= maxval(xst%r3(i)%q)
- endif
- enddo
- do i = 1,ns2d
- ii=ii+1
- if(xst%r2(i)%mykind==r_single)then
- zloc(ii)= maxval(xst%r2(i)%qr4)
- else
- zloc(ii)= maxval(xst%r2(i)%q)
+ zloc(ns3d+i)= sum_mask(xst%r2(i)%q,ihalo=1)
+ zloc(nvars+ns3d+i)= minval(xst%r2(i)%q)
+ zloc(2*nvars+ns3d+i)= maxval(xst%r2(i)%q)
endif
+ nloc(ns3d+i) = real((lat2-2)*(lon2-2), r_kind) ! dim of 2d fields
enddo
! Gather contributions
@@ -444,20 +433,12 @@ subroutine norms_vars(xst,pmin,pmax,psum,pnum)
call mpi_allgather(nloc,size(nloc),mpi_rtype, &
& nall,size(nloc),mpi_rtype, mpi_comm_world,ierror)
- ii=0
- do i=1,ns3d
- ii=ii+1
- psum(ii)=SUM(zall(ii,:))
- pnum(ii)=SUM(nall(ii,:))
- enddo
- do i=1,ns2d
- ii=ii+1
- psum(ii)=SUM(zall(ii,:))
- pnum(ii)=SUM(nall(ii,:))
- enddo
- do ii=1,nvars
- pmin(ii)=MINVAL(zall( nvars+ii,:))
- pmax(ii)=MAXVAL(zall(2*nvars+ii,:))
+!$omp parallel do schedule(static,1) private(i)
+ do i=1,nvars
+ psum(i)=SUM(zall(i,:))
+ pnum(i)=SUM(nall(i,:))
+ pmin(i)=MINVAL(zall( nvars+i,:))
+ pmax(i)=MAXVAL(zall(2*nvars+i,:))
enddo
! Release work space
diff --git a/src/gsi/statsco.f90 b/src/gsi/statsco.f90
index ebef4a31e4..54f28ccfd9 100644
--- a/src/gsi/statsco.f90
+++ b/src/gsi/statsco.f90
@@ -119,7 +119,7 @@ subroutine statsco(stats_co,bwork,awork,ndata)
if (iasim > 0) then
svar = error_co(i)
if (iuse_co(i)/=1) svar = -svar
- rsum = one/float(iasim)
+ rsum = one/real(iasim,r_kind)
icerr = nint(stats_co(2,i))
do j=3,6 ! j=3=obs-mod(w_biascor)
! j=4=(obs-mod(w_biascor))**2
@@ -145,7 +145,7 @@ subroutine statsco(stats_co,bwork,awork,ndata)
do i=1,ndat
if (idisplay(i)) then
cpen=zero
- if (icount_asim(i)>0) cpen=rpenal(i)/float(icount_asim(i))
+ if (icount_asim(i)>0) cpen=rpenal(i)/real(icount_asim(i),r_kind)
write(iout_co,1115) jiter,dplat(i),dtype(i),ndata(i,2), &
ndata(i,3),icount_asim(i),rpenal(i),cpen,qcpenal(i),iqccount_asim(i)
endif
@@ -184,8 +184,8 @@ subroutine statsco(stats_co,bwork,awork,ndata)
num(k)=nint(awork(5*nsig+k+100))
rat=zero ; rat3=zero
if(num(k) > 0) then
- rat=awork(6*nsig+k+100)/float(num(k))
- rat3=awork(3*nsig+k+100)/float(num(k))
+ rat=awork(6*nsig+k+100)/real(num(k),r_kind)
+ rat3=awork(3*nsig+k+100)/real(num(k),r_kind)
end if
ntot=ntot+num(k); o3plty=o3plty+awork(6*nsig+k+100)
o3qcplty=o3qcplty+awork(3*nsig+k+100)
diff --git a/src/gsi/statsconv.f90 b/src/gsi/statsconv.f90
index 7ddb7dea04..fc105515ff 100644
--- a/src/gsi/statsconv.f90
+++ b/src/gsi/statsconv.f90
@@ -2,7 +2,7 @@ subroutine statsconv(mype,&
i_ps,i_uv,i_t,i_q,i_pw,i_rw,i_dw,i_gps,i_sst,i_tcp,i_lag, &
i_gust,i_vis,i_pblh,i_wspd10m,i_td2m,i_mxtm,i_mitm,i_pmsl,i_howv, &
i_tcamt,i_lcbas,i_cldch,i_uwnd10m,i_vwnd10m,&
- i_swcp,i_lwcp,i_dbz,i_ref,bwork,awork,ndata)
+ i_swcp,i_lwcp,i_fed,i_dbz,i_ref,bwork,awork,ndata)
!$$$ subprogram documentation block
! . . . .
! subprogram: statconv prints statistics for conventional data
@@ -74,6 +74,7 @@ subroutine statsconv(mype,&
! i_vwnd10m- index in awork array holding vwnd10m info
! i_swcp - index in awork array holding swcp info
! i_lwcp - index in awork array holding lwcp info
+! i_fed - index in awork array holding fed info
! i_dbz - index in awork array holding dbz info
! i_ref - size of second dimension of awork array
! bwork - array containing information for statistics
@@ -96,12 +97,12 @@ subroutine statsconv(mype,&
iout_gust,iout_vis,iout_pblh,iout_wspd10m,iout_td2m,&
iout_mxtm,iout_mitm,iout_pmsl,iout_howv,iout_tcamt,iout_lcbas,iout_cldch,&
iout_uwnd10m,iout_vwnd10m,&
- iout_dbz,iout_swcp,iout_lwcp,&
+ iout_fed,iout_dbz,iout_swcp,iout_lwcp,&
mype_dw,mype_rw,mype_sst,mype_gps,mype_uv,mype_ps,&
mype_t,mype_pw,mype_q,mype_tcp,ndat,dtype,mype_lag,mype_gust,&
mype_vis,mype_pblh,mype_wspd10m,mype_td2m,mype_mxtm,mype_mitm,&
mype_pmsl,mype_howv,mype_tcamt,mype_lcbas,mype_cldch,mype_uwnd10m,mype_vwnd10m,&
- mype_dbz,mype_swcp,mype_lwcp
+ mype_fed,mype_dbz,mype_swcp,mype_lwcp
use qcmod, only: npres_print,ptop,pbot,ptopq,pbotq
use jfunc, only: first,jiter
use gridmod, only: nsig
@@ -112,7 +113,7 @@ subroutine statsconv(mype,&
integer(i_kind) ,intent(in ) :: mype,i_ps,i_uv,&
i_t,i_q,i_pw,i_rw,i_dw,i_gps,i_sst,i_tcp,i_lag,i_gust,i_vis,i_pblh,&
i_wspd10m,i_td2m,i_mxtm,i_mitm,i_pmsl,i_howv,i_tcamt,i_lcbas,&
- i_cldch,i_uwnd10m,i_vwnd10m,i_swcp,i_lwcp,i_dbz,i_ref
+ i_cldch,i_uwnd10m,i_vwnd10m,i_swcp,i_lwcp,i_fed,i_dbz,i_ref
real(r_kind),dimension(7*nsig+100,i_ref) ,intent(in ) :: awork
real(r_kind),dimension(npres_print,nconvtype,5,3),intent(in ) :: bwork
integer(i_kind),dimension(ndat,3) ,intent(in ) :: ndata
@@ -136,6 +137,7 @@ subroutine statsconv(mype,&
real(r_kind) dwqcplty,tqcplty,qctt,qctrw,rwqcplty,qctdw,qqcplty,qctgps
real(r_kind) gpsqcplty,tpw3,pw3,qctq
real(r_kind) tswcp3,tlwcp3,qctdbz,dbzqcplty
+ real(r_kind) fedmplty,tfed,qctfed,fedqcplty
real(r_kind),dimension(1):: pbotall,ptopall
logical,dimension(nconvtype):: pflag
@@ -154,20 +156,6 @@ subroutine statsconv(mype,&
! Summary report for winds
if(mype==mype_uv) then
-! Open output file so as to point to correct position in output file
- if(first)then
- open(iout_uv)
- else
- open(iout_uv,position='append')
- end if
-
-
-! Compute and write counts, penalties, and ratio of penalty
-! to data counts for each model level
- numssm=nint(awork(6,i_uv)); numgross=nint(awork(4,i_uv))
- umplty=zero; vmplty=zero; uvqcplty=zero ; ntot=0;
- tu=zero; tv=zero ; tuv=zero
- tssm=zero ; qctssm=zero
nread=0
nkeep=0
nreadspd=0
@@ -181,85 +169,92 @@ subroutine statsconv(mype,&
nkeepspd=nkeepspd+ndata(i,3)
end if
end do
- if(nkeep > 0 .or. nkeepspd > 0)then
-! Write header information
- mesage='current vfit of wind data, ranges in m/s$'
+ if(nread > 0 .or. nreadspd > 0)then
+! Open output file so as to point to correct position in output file
+ if(first)then
+ open(iout_uv)
+ else
+ open(iout_uv,position='append')
+ end if
-! Call routine to compute and write count, rms, and penalty information
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'spd' .or. trim(ioctype(j)) == 'uv'
- end do
- call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_uv,pflag)
- numlow = nint(awork(2,i_uv))
- numhgh = nint(awork(3,i_uv))
- write(iout_uv,900) 'wind',numhgh,numlow
- numfailqc=nint(awork(21,i_uv))
-! keep a seperate record of numfailqc for ssmi wind speeds
- numfailqc_ssmi=nint(awork(61,i_uv))
- do k=1,nsig
- num(k)=nint(awork(6*nsig+k+100,i_uv))
- rat1=zero
- rat2=zero
- if(num(k) > 0)then
- rat1=awork(4*nsig+k+100,i_uv)/float(num(k))
- rat2=awork(5*nsig+k+100,i_uv)/float(num(k))
+
+! Compute and write counts, penalties, and ratio of penalty
+! to data counts for each model level
+ numssm=nint(awork(6,i_uv)); numgross=nint(awork(4,i_uv))
+ umplty=zero; vmplty=zero; uvqcplty=zero ; ntot=0;
+ tu=zero; tv=zero ; tuv=zero
+ tssm=zero ; qctssm=zero
+ if(nkeep > 0 .or. nkeepspd > 0)then
+! Write header information
+ mesage='current vfit of wind data, ranges in m/s$'
+
+! Call routine to compute and write count, rms, and penalty information
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'spd' .or. trim(ioctype(j)) == 'uv'
+ end do
+ call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_uv,pflag)
+ numlow = nint(awork(2,i_uv))
+ numhgh = nint(awork(3,i_uv))
+ write(iout_uv,900) 'wind',numhgh,numlow
+ numfailqc=nint(awork(21,i_uv))
+! keep a seperate record of numfailqc for ssmi wind speeds
+ numfailqc_ssmi=nint(awork(61,i_uv))
+ do k=1,nsig
+ num(k)=nint(awork(6*nsig+k+100,i_uv))
+ rat1=zero
+ rat2=zero
+ if(num(k) > 0)then
+ rat1=awork(4*nsig+k+100,i_uv)/real(num(k),r_kind)
+ rat2=awork(5*nsig+k+100,i_uv)/real(num(k),r_kind)
+ end if
+ umplty=umplty+awork(4*nsig+k+100,i_uv)
+ vmplty=vmplty+awork(5*nsig+k+100,i_uv)
+ ntot=ntot+num(k)
+ write(iout_uv,241) 'w',num(k),k,awork(4*nsig+k+100,i_uv),&
+ awork(5*nsig+k+100,i_uv),rat1,rat2
+ end do
+ do k=1,nsig
+ num(k)=nint(awork(6*nsig+k+100,i_uv))
+ rat1=zero
+ rat3=zero
+ if(num(k) > 0)then
+ rat1=(awork(4*nsig+k+100,i_uv)+awork(5*nsig+k+100,i_uv))/real(num(k),r_kind)
+ rat3=awork(3*nsig+k+100,i_uv)/real(num(k),r_kind)
+ end if
+ uvqcplty=uvqcplty+awork(3*nsig+k+100,i_uv)
+ write(iout_uv,240) 'w',num(k),k,awork(4*nsig+k+100,i_uv)+awork(5*nsig+k+100,i_uv), &
+ awork(3*nsig+k+100,i_uv),rat1,rat3
+ end do
+
+! Write statistics gross checks
+ write(iout_uv,920)' number ssm/i winds that fail nonlinear qc =',numfailqc_ssmi
+ write(iout_uv,925) 'wind',numgross,numfailqc
+! Write statistics regarding penalties
+ if(ntot > 0)then
+ tu=umplty/real(ntot,r_kind)
+ tv=vmplty/real(ntot,r_kind)
+ tuv=uvqcplty/real(ntot,r_kind)
end if
- umplty=umplty+awork(4*nsig+k+100,i_uv)
- vmplty=vmplty+awork(5*nsig+k+100,i_uv)
- ntot=ntot+num(k)
- write(iout_uv,241) 'w',num(k),k,awork(4*nsig+k+100,i_uv),&
- awork(5*nsig+k+100,i_uv),rat1,rat2
- end do
- do k=1,nsig
- num(k)=nint(awork(6*nsig+k+100,i_uv))
- rat1=zero
- rat3=zero
- if(num(k) > 0)then
- rat1=(awork(4*nsig+k+100,i_uv)+awork(5*nsig+k+100,i_uv))/float(num(k))
- rat3=awork(3*nsig+k+100,i_uv)/float(num(k))
+ if(numssm > 0)then
+ tssm=awork(5,i_uv)/awork(6,i_uv)
+ qctssm=awork(22,i_uv)/awork(6,i_uv)
end if
- uvqcplty=uvqcplty+awork(3*nsig+k+100,i_uv)
- write(iout_uv,240) 'w',num(k),k,awork(4*nsig+k+100,i_uv)+awork(5*nsig+k+100,i_uv), &
- awork(3*nsig+k+100,i_uv),rat1,rat3
- end do
-
-! Write statistics gross checks
- write(iout_uv,920)' number ssm/i winds that fail nonlinear qc =',numfailqc_ssmi
- write(iout_uv,925) 'wind',numgross,numfailqc
-! Write statistics regarding penalties
- if(ntot > 0)then
- tu=umplty/float(ntot)
- tv=vmplty/float(ntot)
- tuv=uvqcplty/float(ntot)
- end if
- if(numssm > 0)then
- tssm=awork(5,i_uv)/awork(6,i_uv)
- qctssm=awork(22,i_uv)/awork(6,i_uv)
end if
- end if
- write(iout_uv,949) 'u',ntot,umplty,tu
- write(iout_uv,949) 'v',ntot,vmplty,tv
- write(iout_uv,950) 'uv',jiter,nread,nkeep,ntot*2
- write(iout_uv,951) 'uv',umplty+vmplty,uvqcplty,tu+tv,tuv
- write(iout_uv,950) 'spd',jiter,nreadspd,nkeepspd,numssm
- write(iout_uv,951) 'spd',awork(5,i_uv),awork(22,i_uv),tssm,qctssm
+ write(iout_uv,949) 'u',ntot,umplty,tu
+ write(iout_uv,949) 'v',ntot,vmplty,tv
+ write(iout_uv,950) 'uv',jiter,nread,nkeep,ntot*2
+ write(iout_uv,951) 'uv',umplty+vmplty,uvqcplty,tu+tv,tuv
+ write(iout_uv,950) 'spd',jiter,nreadspd,nkeepspd,numssm
+ write(iout_uv,951) 'spd',awork(5,i_uv),awork(22,i_uv),tssm,qctssm
! Close unit receiving summary output
- close(iout_uv)
+ close(iout_uv)
+ end if
end if
! Summary report for gps
if (mype==mype_gps)then
- if(first)then
- open(iout_gps)
- else
- open(iout_gps,position='append')
- end if
-
-
- gpsmplty=zero; gpsqcplty=zero ; ntot=0
- tgps=zero ; qctgps=zero
nread=0
nkeep=0
ctype=' '
@@ -270,67 +265,64 @@ subroutine statsconv(mype,&
ctype=dtype(i)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of gps data in fractional difference$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'gps'
- end do
- call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_gps,pflag)
- do k=1,nsig
- num(k)=nint(awork(5*nsig+k+100,i_gps))
- rat=zero
- rat3=zero
- if(num(k)>0) then
- rat=awork(6*nsig+k+100,i_gps)/float(num(k))
- rat3=awork(3*nsig+k+100,i_gps)/float(num(k))
- end if
- ntot=ntot+num(k); gpsmplty=gpsmplty+awork(6*nsig+k+100,i_gps)
- gpsqcplty=gpsqcplty+awork(3*nsig+k+100,i_gps)
- write(iout_gps,240)'gps',num(k),k,awork(6*nsig+k+100,i_gps), &
- awork(3*nsig+k+100,i_gps),rat,rat3
- end do
- numgross=nint(awork(4,i_gps))
- numfailqc=nint(awork(21,i_gps))
- numfail1_gps=nint(awork(22,i_gps))
- numfail2_gps=nint(awork(23,i_gps))
- numfail3_gps=nint(awork(24,i_gps))
- write(iout_gps,925)'gps',numgross,numfailqc
- write(iout_gps,920)' number of gps obs failed stats qc in NH =',numfail1_gps
- write(iout_gps,920)' number of gps obs failed stats qc in SH =',numfail2_gps
- write(iout_gps,920)' number of gps obs failed stats qc in TR =',numfail3_gps
-
- numlow = nint(awork(2,i_gps))
- numhgh = nint(awork(3,i_gps))
- write(iout_gps,900) 'gps',numhgh,numlow
- if(ntot > 0) then
- tgps=gpsmplty/ntot
- qctgps=gpsqcplty/ntot
- endif
- end if
+ if(nread > 0)then
+ if(first)then
+ open(iout_gps)
+ else
+ open(iout_gps,position='append')
+ end if
- write(iout_gps,950) ctype,jiter,nread,nkeep,ntot
- write(iout_gps,951) ctype,gpsmplty,gpsqcplty,tgps,qctgps
- close(iout_gps)
- endif
+ gpsmplty=zero; gpsqcplty=zero ; ntot=0
+ tgps=zero ; qctgps=zero
+ if(nkeep > 0)then
+ mesage='current fit of gps data in fractional difference$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'gps'
+ end do
+ call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_gps,pflag)
+ do k=1,nsig
+ num(k)=nint(awork(5*nsig+k+100,i_gps))
+ rat=zero
+ rat3=zero
+ if(num(k)>0) then
+ rat=awork(6*nsig+k+100,i_gps)/real(num(k),r_kind)
+ rat3=awork(3*nsig+k+100,i_gps)/real(num(k),r_kind)
+ end if
+ ntot=ntot+num(k); gpsmplty=gpsmplty+awork(6*nsig+k+100,i_gps)
+ gpsqcplty=gpsqcplty+awork(3*nsig+k+100,i_gps)
+ write(iout_gps,240)'gps',num(k),k,awork(6*nsig+k+100,i_gps), &
+ awork(3*nsig+k+100,i_gps),rat,rat3
+ end do
+ numgross=nint(awork(4,i_gps))
+ numfailqc=nint(awork(21,i_gps))
+ numfail1_gps=nint(awork(22,i_gps))
+ numfail2_gps=nint(awork(23,i_gps))
+ numfail3_gps=nint(awork(24,i_gps))
+ write(iout_gps,925)'gps',numgross,numfailqc
+ write(iout_gps,920)' number of gps obs failed stats qc in NH =',numfail1_gps
+ write(iout_gps,920)' number of gps obs failed stats qc in SH =',numfail2_gps
+ write(iout_gps,920)' number of gps obs failed stats qc in TR =',numfail3_gps
+
+ numlow = nint(awork(2,i_gps))
+ numhgh = nint(awork(3,i_gps))
+ write(iout_gps,900) 'gps',numhgh,numlow
+ if(ntot > 0) then
+ tgps=gpsmplty/ntot
+ qctgps=gpsqcplty/ntot
+ endif
+ end if
+ write(iout_gps,950) ctype,jiter,nread,nkeep,ntot
+ write(iout_gps,951) ctype,gpsmplty,gpsqcplty,tgps,qctgps
-! Summary report for specific humidity
- if(mype==mype_q) then
- if(first)then
- open(iout_q)
- else
- open(iout_q,position='append')
+ close(iout_gps)
end if
+ endif
- mesage='current fit of q data, units in per-cent of guess q-sat$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'q'
- end do
- call dtast(bwork,npres_print,pbotq,ptopq,mesage,jiter,iout_q,pflag)
- qmplty=zero; qqcplty=zero ; ntot=0
- tq=zero ; qctq=zero
+! Summary report for specific humidity
+ if(mype==mype_q) then
nread=0
nkeep=0
do i=1,ndat
@@ -339,53 +331,61 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- do k=1,nsig
- num(k)=nint(awork(k+6*nsig+100,i_q))
- rat=zero
- rat3=zero
- if(num(k) > 0)then
- rat=awork(5*nsig+k+100,i_q)/float(num(k))
- rat3=awork(3*nsig+k+100,i_q)/float(num(k))
- end if
- qmplty=qmplty+awork(5*nsig+k+100,i_q)
- qqcplty=qqcplty+awork(3*nsig+k+100,i_q)
- ntot=ntot+num(k)
- write(iout_q,240) 'q',num(k),k,awork(5*nsig+k+100,i_q), &
- awork(3*nsig+k+100,i_q),rat,rat3
+ if(nread > 0)then
+ if(first)then
+ open(iout_q)
+ else
+ open(iout_q,position='append')
+ end if
+
+ mesage='current fit of q data, units in per-cent of guess q-sat$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'q'
end do
- grsmlt=five
- numgrsq=nint(awork(4,i_q))
- numfailqc=nint(awork(21,i_q))
- write(iout_q,924)' (scaled as precent of guess specific humidity)'
- write(iout_q,925) 'q',numgrsq,numfailqc
- write(iout_q,975) grsmlt,'q',awork(5,i_q)
- numlow = nint(awork(2,i_q))
- numhgh = nint(awork(3,i_q))
- write(iout_q,900) 'q',numhgh,numlow
- if(ntot > 0) then
- tq=qmplty/float(ntot)
- qctq=qqcplty/float(ntot)
+ call dtast(bwork,npres_print,pbotq,ptopq,mesage,jiter,iout_q,pflag)
+
+ qmplty=zero; qqcplty=zero ; ntot=0
+ tq=zero ; qctq=zero
+ if(nkeep > 0)then
+ do k=1,nsig
+ num(k)=nint(awork(k+6*nsig+100,i_q))
+ rat=zero
+ rat3=zero
+ if(num(k) > 0)then
+ rat=awork(5*nsig+k+100,i_q)/real(num(k),r_kind)
+ rat3=awork(3*nsig+k+100,i_q)/real(num(k),r_kind)
+ end if
+ qmplty=qmplty+awork(5*nsig+k+100,i_q)
+ qqcplty=qqcplty+awork(3*nsig+k+100,i_q)
+ ntot=ntot+num(k)
+ write(iout_q,240) 'q',num(k),k,awork(5*nsig+k+100,i_q), &
+ awork(3*nsig+k+100,i_q),rat,rat3
+ end do
+ grsmlt=five
+ numgrsq=nint(awork(4,i_q))
+ numfailqc=nint(awork(21,i_q))
+ write(iout_q,924)' (scaled as precent of guess specific humidity)'
+ write(iout_q,925) 'q',numgrsq,numfailqc
+ write(iout_q,975) grsmlt,'q',awork(5,i_q)
+ numlow = nint(awork(2,i_q))
+ numhgh = nint(awork(3,i_q))
+ write(iout_q,900) 'q',numhgh,numlow
+ if(ntot > 0) then
+ tq=qmplty/real(ntot,r_kind)
+ qctq=qqcplty/real(ntot,r_kind)
+ end if
end if
- end if
- write(iout_q,950) 'q',jiter,nread,nkeep,ntot
- write(iout_q,951) 'q',qmplty,qqcplty,tq,qctq
+ write(iout_q,950) 'q',jiter,nread,nkeep,ntot
+ write(iout_q,951) 'q',qmplty,qqcplty,tq,qctq
- close(iout_q)
+ close(iout_q)
+ end if
end if
! Summary report for surface pressure
if(mype==mype_ps) then
- if(first)then
- open(iout_ps)
- else
- open(iout_ps,position='append')
- end if
-
- nump=nint(awork(5,i_ps))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -394,40 +394,42 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of surface pressure data, ranges in mb$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'ps'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_ps,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_ps)
+ else
+ open(iout_ps,position='append')
+ end if
+
+ nump=nint(awork(5,i_ps))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of surface pressure data, ranges in mb$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'ps'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_ps,pflag)
- numgross=nint(awork(6,i_ps))
- numfailqc=nint(awork(21,i_ps))
- write(iout_ps,925) 'psfc',numgross,numfailqc
- if(nump > 0)then
- pw=awork(4,i_ps)/float(nump)
- pw3=awork(22,i_ps)/float(nump)
+ numgross=nint(awork(6,i_ps))
+ numfailqc=nint(awork(21,i_ps))
+ write(iout_ps,925) 'psfc',numgross,numfailqc
+ if(nump > 0)then
+ pw=awork(4,i_ps)/real(nump,r_kind)
+ pw3=awork(22,i_ps)/real(nump,r_kind)
+ end if
end if
- end if
- write(iout_ps,950) 'psfc',jiter,nread,nkeep,nump
- write(iout_ps,951) 'psfc',awork(4,i_ps),awork(22,i_ps),pw,pw3
+ write(iout_ps,950) 'psfc',jiter,nread,nkeep,nump
+ write(iout_ps,951) 'psfc',awork(4,i_ps),awork(22,i_ps),pw,pw3
- close(iout_ps)
+ close(iout_ps)
+ end if
end if
! Summary report for total precipitable water
if(mype==mype_pw) then
- if(first)then
- open(iout_pw)
- else
- open(iout_pw,position='append')
- end if
- nsuperp=nint(awork(4,i_pw))
-
- tpw=zero ; tpw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -436,41 +438,42 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of precip. water data, ranges in mm$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'pw'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_pw,pflag)
-
- numgrspw=nint(awork(6,i_pw))
- numfailqc=nint(awork(21,i_pw))
- grsmlt=three
- tpw=zero
- tpw3=zero
- if(nsuperp > 0)then
- tpw=awork(5,i_pw)/nsuperp
- tpw3=awork(22,i_pw)/nsuperp
- end if
- write(iout_pw,925) 'p.w.',numgrspw,numfailqc
- write(iout_pw,975) grsmlt,'p.w.',awork(7,i_pw)
- end if
- write(iout_pw,950) 'pw',jiter,nread,nkeep,nsuperp
- write(iout_pw,951) 'pw',awork(5,i_pw),awork(22,i_pw),tpw,tpw3
+ if(nread > 0)then
+ if(first)then
+ open(iout_pw)
+ else
+ open(iout_pw,position='append')
+ end if
+ tpw=zero ; tpw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of precip. water data, ranges in mm$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'pw'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_pw,pflag)
+
+ numgrspw=nint(awork(6,i_pw))
+ numfailqc=nint(awork(21,i_pw))
+ grsmlt=three
+ tpw=zero
+ tpw3=zero
+ nsuperp=nint(awork(4,i_pw))
+ if(nsuperp > 0)then
+ tpw=awork(5,i_pw)/nsuperp
+ tpw3=awork(22,i_pw)/nsuperp
+ end if
+ write(iout_pw,925) 'p.w.',numgrspw,numfailqc
+ write(iout_pw,975) grsmlt,'p.w.',awork(7,i_pw)
+ end if
+ write(iout_pw,950) 'pw',jiter,nread,nkeep,nsuperp
+ write(iout_pw,951) 'pw',awork(5,i_pw),awork(22,i_pw),tpw,tpw3
- close(iout_pw)
+ close(iout_pw)
+ end if
end if
! Summary report for conventional sst
if(mype==mype_sst) then
- if(first)then
- open(iout_sst)
- else
- open(iout_sst,position='append')
- end if
-
- numsst=nint(awork(5,i_sst))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -479,37 +482,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional sst data, ranges in C$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'sst'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_sst,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_sst)
+ else
+ open(iout_sst,position='append')
+ end if
- numgross=nint(awork(6,i_sst))
- numfailqc=nint(awork(21,i_sst))
- if(numsst > 0)then
- pw=awork(4,i_sst)/numsst
- pw3=awork(22,i_sst)/numsst
+ numsst=nint(awork(5,i_sst))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional sst data, ranges in C$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'sst'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_sst,pflag)
+
+ numgross=nint(awork(6,i_sst))
+ numfailqc=nint(awork(21,i_sst))
+ if(numsst > 0)then
+ pw=awork(4,i_sst)/numsst
+ pw3=awork(22,i_sst)/numsst
+ end if
+ write(iout_sst,925) 'sst',numgross,numfailqc
end if
- write(iout_sst,925) 'sst',numgross,numfailqc
- end if
- write(iout_sst,950) 'sst',jiter,nread,nkeep,numsst
- write(iout_sst,951) 'sst',awork(4,i_sst),awork(22,i_sst),pw,pw3
+ write(iout_sst,950) 'sst',jiter,nread,nkeep,numsst
+ write(iout_sst,951) 'sst',awork(4,i_sst),awork(22,i_sst),pw,pw3
- close(iout_sst)
+ close(iout_sst)
+ end if
end if
! Summary report for conventional gust
if(mype==mype_gust) then
- if(first)then
- open(iout_gust)
- else
- open(iout_gust,position='append')
- end if
-
- numgust=nint(awork(5,i_gust))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -518,37 +523,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional gust data, ranges in m/s$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'gust'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_gust,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_gust)
+ else
+ open(iout_gust,position='append')
+ end if
- numgross=nint(awork(6,i_gust))
- numfailqc=nint(awork(21,i_gust))
- if(numgust > 0)then
- pw=awork(4,i_gust)/numgust
- pw3=awork(22,i_gust)/numgust
+ numgust=nint(awork(5,i_gust))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional gust data, ranges in m/s$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'gust'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_gust,pflag)
+
+ numgross=nint(awork(6,i_gust))
+ numfailqc=nint(awork(21,i_gust))
+ if(numgust > 0)then
+ pw=awork(4,i_gust)/numgust
+ pw3=awork(22,i_gust)/numgust
+ end if
+ write(iout_gust,925) 'gust',numgross,numfailqc
end if
- write(iout_gust,925) 'gust',numgross,numfailqc
- end if
- write(iout_gust,950) 'gust',jiter,nread,nkeep,numgust
- write(iout_gust,951) 'gust',awork(4,i_gust),awork(22,i_gust),pw,pw3
+ write(iout_gust,950) 'gust',jiter,nread,nkeep,numgust
+ write(iout_gust,951) 'gust',awork(4,i_gust),awork(22,i_gust),pw,pw3
- close(iout_gust)
+ close(iout_gust)
+ end if
end if
! Summary report for conventional vis
if(mype==mype_vis) then
- if(first)then
- open(iout_vis)
- else
- open(iout_vis,position='append')
- end if
-
- numvis=nint(awork(5,i_vis))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -557,37 +564,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional vis data, ranges in m$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'vis'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_vis,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_vis)
+ else
+ open(iout_vis,position='append')
+ end if
- numgross=nint(awork(6,i_vis))
- numfailqc=nint(awork(21,i_vis))
- if(numvis > 0)then
- pw=awork(4,i_vis)/numvis
- pw3=awork(22,i_vis)/numvis
+ numvis=nint(awork(5,i_vis))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional vis data, ranges in m$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'vis'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_vis,pflag)
+
+ numgross=nint(awork(6,i_vis))
+ numfailqc=nint(awork(21,i_vis))
+ if(numvis > 0)then
+ pw=awork(4,i_vis)/numvis
+ pw3=awork(22,i_vis)/numvis
+ end if
+ write(iout_vis,925) 'vis',numgross,numfailqc
end if
- write(iout_vis,925) 'vis',numgross,numfailqc
- end if
- write(iout_vis,950) 'vis',jiter,nread,nkeep,numvis
- write(iout_vis,951) 'vis',awork(4,i_vis),awork(22,i_vis),pw,pw3
+ write(iout_vis,950) 'vis',jiter,nread,nkeep,numvis
+ write(iout_vis,951) 'vis',awork(4,i_vis),awork(22,i_vis),pw,pw3
- close(iout_vis)
+ close(iout_vis)
+ end if
end if
! Summary report for conventional pblh
if(mype==mype_pblh) then
- if(first)then
- open(iout_pblh)
- else
- open(iout_pblh,position='append')
- end if
-
- numpblh=nint(awork(5,i_pblh))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -596,37 +605,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional pblh data, ranges in m$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'pblh'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_pblh,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_pblh)
+ else
+ open(iout_pblh,position='append')
+ end if
- numgross=nint(awork(6,i_pblh))
- numfailqc=nint(awork(21,i_pblh))
- if(numpblh > 0)then
- pw=awork(4,i_pblh)/numpblh
- pw3=awork(22,i_pblh)/numpblh
+ numpblh=nint(awork(5,i_pblh))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional pblh data, ranges in m$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'pblh'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_pblh,pflag)
+
+ numgross=nint(awork(6,i_pblh))
+ numfailqc=nint(awork(21,i_pblh))
+ if(numpblh > 0)then
+ pw=awork(4,i_pblh)/numpblh
+ pw3=awork(22,i_pblh)/numpblh
+ end if
+ write(iout_pblh,925) 'pblh',numgross,numfailqc
end if
- write(iout_pblh,925) 'pblh',numgross,numfailqc
- end if
- write(iout_pblh,950) 'pblh',jiter,nread,nkeep,numpblh
- write(iout_pblh,951) 'pblh',awork(4,i_pblh),awork(22,i_pblh),pw,pw3
+ write(iout_pblh,950) 'pblh',jiter,nread,nkeep,numpblh
+ write(iout_pblh,951) 'pblh',awork(4,i_pblh),awork(22,i_pblh),pw,pw3
- close(iout_pblh)
+ close(iout_pblh)
+ end if
end if
! Summary report for conventional wspd10m
if(mype==mype_wspd10m) then
- if(first)then
- open(iout_wspd10m)
- else
- open(iout_wspd10m,position='append')
- end if
-
- numwspd10m=nint(awork(5,i_wspd10m))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -635,37 +646,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional wspd10m data, ranges in m/s$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'wspd10m'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_wspd10m,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_wspd10m)
+ else
+ open(iout_wspd10m,position='append')
+ end if
- numgross=nint(awork(6,i_wspd10m))
- numfailqc=nint(awork(21,i_wspd10m))
- if(numwspd10m > 0)then
- pw=awork(4,i_wspd10m)/numwspd10m
- pw3=awork(22,i_wspd10m)/numwspd10m
+ numwspd10m=nint(awork(5,i_wspd10m))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional wspd10m data, ranges in m/s$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'wspd10m'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_wspd10m,pflag)
+
+ numgross=nint(awork(6,i_wspd10m))
+ numfailqc=nint(awork(21,i_wspd10m))
+ if(numwspd10m > 0)then
+ pw=awork(4,i_wspd10m)/numwspd10m
+ pw3=awork(22,i_wspd10m)/numwspd10m
+ end if
+ write(iout_wspd10m,925) 'wspd10m',numgross,numfailqc
end if
- write(iout_wspd10m,925) 'wspd10m',numgross,numfailqc
- end if
- write(iout_wspd10m,950) 'wspd10m',jiter,nread,nkeep,numwspd10m
- write(iout_wspd10m,951) 'wspd10m',awork(4,i_wspd10m),awork(22,i_wspd10m),pw,pw3
+ write(iout_wspd10m,950) 'wspd10m',jiter,nread,nkeep,numwspd10m
+ write(iout_wspd10m,951) 'wspd10m',awork(4,i_wspd10m),awork(22,i_wspd10m),pw,pw3
- close(iout_wspd10m)
+ close(iout_wspd10m)
+ end if
end if
! Summary report for conventional td2m
if(mype==mype_td2m) then
- if(first)then
- open(iout_td2m)
- else
- open(iout_td2m,position='append')
- end if
-
- numtd2m=nint(awork(5,i_td2m))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -674,37 +687,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional td2m data, ranges in K $'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'td2m'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_td2m,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_td2m)
+ else
+ open(iout_td2m,position='append')
+ end if
- numgross=nint(awork(6,i_td2m))
- numfailqc=nint(awork(21,i_td2m))
- if(numtd2m > 0)then
- pw=awork(4,i_td2m)/numtd2m
- pw3=awork(22,i_td2m)/numtd2m
+ numtd2m=nint(awork(5,i_td2m))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional td2m data, ranges in K $'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'td2m'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_td2m,pflag)
+
+ numgross=nint(awork(6,i_td2m))
+ numfailqc=nint(awork(21,i_td2m))
+ if(numtd2m > 0)then
+ pw=awork(4,i_td2m)/numtd2m
+ pw3=awork(22,i_td2m)/numtd2m
+ end if
+ write(iout_td2m,925) 'td2m',numgross,numfailqc
end if
- write(iout_td2m,925) 'td2m',numgross,numfailqc
- end if
- write(iout_td2m,950) 'td2m',jiter,nread,nkeep,numtd2m
- write(iout_td2m,951) 'td2m',awork(4,i_td2m),awork(22,i_td2m),pw,pw3
+ write(iout_td2m,950) 'td2m',jiter,nread,nkeep,numtd2m
+ write(iout_td2m,951) 'td2m',awork(4,i_td2m),awork(22,i_td2m),pw,pw3
- close(iout_td2m)
+ close(iout_td2m)
+ end if
end if
! Summary report for conventional mxtm
if(mype==mype_mxtm) then
- if(first)then
- open(iout_mxtm)
- else
- open(iout_mxtm,position='append')
- end if
-
- nummxtm=nint(awork(5,i_mxtm))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -713,37 +728,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional mxtm data, ranges in K $'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'mxtm'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_mxtm,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_mxtm)
+ else
+ open(iout_mxtm,position='append')
+ end if
- numgross=nint(awork(6,i_mxtm))
- numfailqc=nint(awork(21,i_mxtm))
- if(nummxtm > 0)then
- pw=awork(4,i_mxtm)/nummxtm
- pw3=awork(22,i_mxtm)/nummxtm
+ nummxtm=nint(awork(5,i_mxtm))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional mxtm data, ranges in K $'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'mxtm'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_mxtm,pflag)
+
+ numgross=nint(awork(6,i_mxtm))
+ numfailqc=nint(awork(21,i_mxtm))
+ if(nummxtm > 0)then
+ pw=awork(4,i_mxtm)/nummxtm
+ pw3=awork(22,i_mxtm)/nummxtm
+ end if
+ write(iout_mxtm,925) 'mxtm',numgross,numfailqc
end if
- write(iout_mxtm,925) 'mxtm',numgross,numfailqc
- end if
- write(iout_mxtm,950) 'mxtm',jiter,nread,nkeep,nummxtm
- write(iout_mxtm,951) 'mxtm',awork(4,i_mxtm),awork(22,i_mxtm),pw,pw3
+ write(iout_mxtm,950) 'mxtm',jiter,nread,nkeep,nummxtm
+ write(iout_mxtm,951) 'mxtm',awork(4,i_mxtm),awork(22,i_mxtm),pw,pw3
- close(iout_mxtm)
+ close(iout_mxtm)
+ end if
end if
! Summary report for conventional mitm
if(mype==mype_mitm) then
- if(first)then
- open(iout_mitm)
- else
- open(iout_mitm,position='append')
- end if
-
- nummitm=nint(awork(5,i_mitm))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -752,37 +769,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional mitm data, ranges in K $'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'mitm'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_mitm,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_mitm)
+ else
+ open(iout_mitm,position='append')
+ end if
- numgross=nint(awork(6,i_mitm))
- numfailqc=nint(awork(21,i_mitm))
- if(nummitm > 0)then
- pw=awork(4,i_mitm)/nummitm
- pw3=awork(22,i_mitm)/nummitm
+ nummitm=nint(awork(5,i_mitm))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional mitm data, ranges in K $'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'mitm'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_mitm,pflag)
+
+ numgross=nint(awork(6,i_mitm))
+ numfailqc=nint(awork(21,i_mitm))
+ if(nummitm > 0)then
+ pw=awork(4,i_mitm)/nummitm
+ pw3=awork(22,i_mitm)/nummitm
+ end if
+ write(iout_mitm,925) 'mitm',numgross,numfailqc
end if
- write(iout_mitm,925) 'mitm',numgross,numfailqc
- end if
- write(iout_mitm,950) 'mitm',jiter,nread,nkeep,nummitm
- write(iout_mitm,951) 'mitm',awork(4,i_mitm),awork(22,i_mitm),pw,pw3
+ write(iout_mitm,950) 'mitm',jiter,nread,nkeep,nummitm
+ write(iout_mitm,951) 'mitm',awork(4,i_mitm),awork(22,i_mitm),pw,pw3
- close(iout_mitm)
+ close(iout_mitm)
+ end if
end if
! Summary report for conventional pmsl
if(mype==mype_pmsl) then
- if(first)then
- open(iout_pmsl)
- else
- open(iout_pmsl,position='append')
- end if
-
- numpmsl=nint(awork(5,i_pmsl))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -791,37 +810,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional pmsl data, ranges in hPa $'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'pmsl'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_pmsl,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_pmsl)
+ else
+ open(iout_pmsl,position='append')
+ end if
- numgross=nint(awork(6,i_pmsl))
- numfailqc=nint(awork(21,i_pmsl))
- if(numpmsl > 0)then
- pw=awork(4,i_pmsl)/numpmsl
- pw3=awork(22,i_pmsl)/numpmsl
+ numpmsl=nint(awork(5,i_pmsl))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional pmsl data, ranges in hPa $'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'pmsl'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_pmsl,pflag)
+
+ numgross=nint(awork(6,i_pmsl))
+ numfailqc=nint(awork(21,i_pmsl))
+ if(numpmsl > 0)then
+ pw=awork(4,i_pmsl)/numpmsl
+ pw3=awork(22,i_pmsl)/numpmsl
+ end if
+ write(iout_pmsl,925) 'pmsl',numgross,numfailqc
end if
- write(iout_pmsl,925) 'pmsl',numgross,numfailqc
- end if
- write(iout_pmsl,950) 'pmsl',jiter,nread,nkeep,numpmsl
- write(iout_pmsl,951) 'pmsl',awork(4,i_pmsl),awork(22,i_pmsl),pw,pw3
+ write(iout_pmsl,950) 'pmsl',jiter,nread,nkeep,numpmsl
+ write(iout_pmsl,951) 'pmsl',awork(4,i_pmsl),awork(22,i_pmsl),pw,pw3
- close(iout_pmsl)
+ close(iout_pmsl)
+ end if
end if
! Summary report for conventional howv
if(mype==mype_howv) then
- if(first)then
- open(iout_howv)
- else
- open(iout_howv,position='append')
- end if
-
- numhowv=nint(awork(5,i_howv))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -830,37 +851,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional howv data, ranges in m $'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'howv'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_howv,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_howv)
+ else
+ open(iout_howv,position='append')
+ end if
- numgross=nint(awork(6,i_howv))
- numfailqc=nint(awork(21,i_howv))
- if(numhowv > 0)then
- pw=awork(4,i_howv)/numhowv
- pw3=awork(22,i_howv)/numhowv
+ numhowv=nint(awork(5,i_howv))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional howv data, ranges in m $'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'howv'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_howv,pflag)
+
+ numgross=nint(awork(6,i_howv))
+ numfailqc=nint(awork(21,i_howv))
+ if(numhowv > 0)then
+ pw=awork(4,i_howv)/numhowv
+ pw3=awork(22,i_howv)/numhowv
+ end if
+ write(iout_howv,925) 'howv',numgross,numfailqc
end if
- write(iout_howv,925) 'howv',numgross,numfailqc
- end if
- write(iout_howv,950) 'howv',jiter,nread,nkeep,numhowv
- write(iout_howv,951) 'howv',awork(4,i_howv),awork(22,i_howv),pw,pw3
+ write(iout_howv,950) 'howv',jiter,nread,nkeep,numhowv
+ write(iout_howv,951) 'howv',awork(4,i_howv),awork(22,i_howv),pw,pw3
- close(iout_howv)
+ close(iout_howv)
+ end if
end if
! Summary report for tcamt
if(mype==mype_tcamt) then
- if(first)then
- open(iout_tcamt)
- else
- open(iout_tcamt,position='append')
- end if
-
- numtcamt=nint(awork(5,i_tcamt))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -869,37 +892,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional tcamt data, ranges in %$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'tcamt'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_tcamt,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_tcamt)
+ else
+ open(iout_tcamt,position='append')
+ end if
- numgross=nint(awork(6,i_tcamt))
- numfailqc=nint(awork(21,i_tcamt))
- if(numtcamt > 0)then
- pw=awork(4,i_tcamt)/numtcamt
- pw3=awork(22,i_tcamt)/numtcamt
+ numtcamt=nint(awork(5,i_tcamt))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional tcamt data, ranges in %$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'tcamt'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_tcamt,pflag)
+
+ numgross=nint(awork(6,i_tcamt))
+ numfailqc=nint(awork(21,i_tcamt))
+ if(numtcamt > 0)then
+ pw=awork(4,i_tcamt)/numtcamt
+ pw3=awork(22,i_tcamt)/numtcamt
+ end if
+ write(iout_tcamt,925) 'tcamt',numgross,numfailqc
end if
- write(iout_tcamt,925) 'tcamt',numgross,numfailqc
- end if
- write(iout_tcamt,950) 'tcamt',jiter,nread,nkeep,numtcamt
- write(iout_tcamt,951) 'tcamt',awork(4,i_tcamt),awork(22,i_tcamt),pw,pw3
+ write(iout_tcamt,950) 'tcamt',jiter,nread,nkeep,numtcamt
+ write(iout_tcamt,951) 'tcamt',awork(4,i_tcamt),awork(22,i_tcamt),pw,pw3
- close(iout_tcamt)
+ close(iout_tcamt)
+ end if
end if
! Summary report for lcbas
if(mype==mype_lcbas) then
- if(first)then
- open(iout_lcbas)
- else
- open(iout_lcbas,position='append')
- end if
-
- numlcbas=nint(awork(5,i_lcbas))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -908,37 +933,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional lcbas data, ranges in m$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'lcbas'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_lcbas,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_lcbas)
+ else
+ open(iout_lcbas,position='append')
+ end if
- numgross=nint(awork(6,i_lcbas))
- numfailqc=nint(awork(21,i_lcbas))
- if(numlcbas > 0)then
- pw=awork(4,i_lcbas)/numlcbas
- pw3=awork(22,i_lcbas)/numlcbas
+ numlcbas=nint(awork(5,i_lcbas))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional lcbas data, ranges in m$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'lcbas'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_lcbas,pflag)
+
+ numgross=nint(awork(6,i_lcbas))
+ numfailqc=nint(awork(21,i_lcbas))
+ if(numlcbas > 0)then
+ pw=awork(4,i_lcbas)/numlcbas
+ pw3=awork(22,i_lcbas)/numlcbas
+ end if
+ write(iout_lcbas,925) 'lcbas',numgross,numfailqc
end if
- write(iout_lcbas,925) 'lcbas',numgross,numfailqc
- end if
- write(iout_lcbas,950) 'lcbas',jiter,nread,nkeep,numlcbas
- write(iout_lcbas,951) 'lcbas',awork(4,i_lcbas),awork(22,i_lcbas),pw,pw3
+ write(iout_lcbas,950) 'lcbas',jiter,nread,nkeep,numlcbas
+ write(iout_lcbas,951) 'lcbas',awork(4,i_lcbas),awork(22,i_lcbas),pw,pw3
- close(iout_lcbas)
+ close(iout_lcbas)
+ end if
end if
! Summary report for conventional cldch
if(mype==mype_cldch) then
- if(first)then
- open(iout_cldch)
- else
- open(iout_cldch,position='append')
- end if
-
- numcldch=nint(awork(5,i_cldch))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -947,37 +974,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional cldch data, ranges in m$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'cldch'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_cldch,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_cldch)
+ else
+ open(iout_cldch,position='append')
+ end if
- numgross=nint(awork(6,i_cldch))
- numfailqc=nint(awork(21,i_cldch))
- if(numcldch > 0)then
- pw=awork(4,i_cldch)/numcldch
- pw3=awork(22,i_cldch)/numcldch
+ numcldch=nint(awork(5,i_cldch))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional cldch data, ranges in m$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'cldch'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_cldch,pflag)
+
+ numgross=nint(awork(6,i_cldch))
+ numfailqc=nint(awork(21,i_cldch))
+ if(numcldch > 0)then
+ pw=awork(4,i_cldch)/numcldch
+ pw3=awork(22,i_cldch)/numcldch
+ end if
+ write(iout_cldch,925) 'cldch',numgross,numfailqc
end if
- write(iout_cldch,925) 'cldch',numgross,numfailqc
- end if
- write(iout_cldch,950) 'cldch',jiter,nread,nkeep,numcldch
- write(iout_cldch,951) 'cldch',awork(4,i_cldch),awork(22,i_cldch),pw,pw3
+ write(iout_cldch,950) 'cldch',jiter,nread,nkeep,numcldch
+ write(iout_cldch,951) 'cldch',awork(4,i_cldch),awork(22,i_cldch),pw,pw3
- close(iout_cldch)
+ close(iout_cldch)
+ end if
end if
! Summary report for conventional uwnd10m
if(mype==mype_uwnd10m) then
- if(first)then
- open(iout_uwnd10m)
- else
- open(iout_uwnd10m,position='append')
- end if
-
- numuwnd10m=nint(awork(5,i_uwnd10m))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -986,37 +1015,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional uwnd10m data, ranges in m/s$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'uwnd10m'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_uwnd10m,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_uwnd10m)
+ else
+ open(iout_uwnd10m,position='append')
+ end if
- numgross=nint(awork(6,i_uwnd10m))
- numfailqc=nint(awork(21,i_uwnd10m))
- if(numuwnd10m > 0)then
- pw=awork(4,i_uwnd10m)/numuwnd10m
- pw3=awork(22,i_uwnd10m)/numuwnd10m
+ numuwnd10m=nint(awork(5,i_uwnd10m))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional uwnd10m data, ranges in m/s$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'uwnd10m'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_uwnd10m,pflag)
+
+ numgross=nint(awork(6,i_uwnd10m))
+ numfailqc=nint(awork(21,i_uwnd10m))
+ if(numuwnd10m > 0)then
+ pw=awork(4,i_uwnd10m)/numuwnd10m
+ pw3=awork(22,i_uwnd10m)/numuwnd10m
+ end if
+ write(iout_uwnd10m,925) 'uwnd10m',numgross,numfailqc
end if
- write(iout_uwnd10m,925) 'uwnd10m',numgross,numfailqc
- end if
- write(iout_uwnd10m,950) 'uwnd10m',jiter,nread,nkeep,numuwnd10m
- write(iout_uwnd10m,951) 'uwnd10m',awork(4,i_uwnd10m),awork(22,i_uwnd10m),pw,pw3
+ write(iout_uwnd10m,950) 'uwnd10m',jiter,nread,nkeep,numuwnd10m
+ write(iout_uwnd10m,951) 'uwnd10m',awork(4,i_uwnd10m),awork(22,i_uwnd10m),pw,pw3
- close(iout_uwnd10m)
+ close(iout_uwnd10m)
+ end if
end if
! Summary report for conventional vwnd10m
if(mype==mype_vwnd10m) then
- if(first)then
- open(iout_vwnd10m)
- else
- open(iout_vwnd10m,position='append')
- end if
-
- numvwnd10m=nint(awork(5,i_vwnd10m))
- pw=zero ; pw3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -1025,37 +1056,39 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of conventional vwnd10m data, ranges in m/s$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'vwnd10m'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_vwnd10m,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_vwnd10m)
+ else
+ open(iout_vwnd10m,position='append')
+ end if
- numgross=nint(awork(6,i_vwnd10m))
- numfailqc=nint(awork(21,i_vwnd10m))
- if(numvwnd10m > 0)then
- pw=awork(4,i_vwnd10m)/numvwnd10m
- pw3=awork(22,i_vwnd10m)/numvwnd10m
+ numvwnd10m=nint(awork(5,i_vwnd10m))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of conventional vwnd10m data, ranges in m/s$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'vwnd10m'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_vwnd10m,pflag)
+
+ numgross=nint(awork(6,i_vwnd10m))
+ numfailqc=nint(awork(21,i_vwnd10m))
+ if(numvwnd10m > 0)then
+ pw=awork(4,i_vwnd10m)/numvwnd10m
+ pw3=awork(22,i_vwnd10m)/numvwnd10m
+ end if
+ write(iout_vwnd10m,925) 'vwnd10m',numgross,numfailqc
end if
- write(iout_vwnd10m,925) 'vwnd10m',numgross,numfailqc
- end if
- write(iout_vwnd10m,950) 'vwnd10m',jiter,nread,nkeep,numvwnd10m
- write(iout_vwnd10m,951) 'vwnd10m',awork(4,i_vwnd10m),awork(22,i_vwnd10m),pw,pw3
+ write(iout_vwnd10m,950) 'vwnd10m',jiter,nread,nkeep,numvwnd10m
+ write(iout_vwnd10m,951) 'vwnd10m',awork(4,i_vwnd10m),awork(22,i_vwnd10m),pw,pw3
- close(iout_vwnd10m)
+ close(iout_vwnd10m)
+ end if
end if
! Summary report for temperature
if (mype==mype_t)then
- if(first)then
- open(iout_t)
- else
- open(iout_t,position='append')
- end if
-
- tmplty=zero; tqcplty=zero ; ntot=0
- tt=zero ; qctt=zero
nread=0
nkeep=0
do i=1,ndat
@@ -1064,54 +1097,56 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of temperature data, ranges in K $'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 't'
- end do
- call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_t,pflag)
- do k=1,nsig
- num(k)=nint(awork(5*nsig+k+100,i_t))
- rat=zero ; rat3=zero
- if(num(k) > 0) then
- rat=awork(6*nsig+k+100,i_t)/float(num(k))
- rat3=awork(3*nsig+k+100,i_t)/float(num(k))
+ if(nread > 0)then
+ if(first)then
+ open(iout_t)
+ else
+ open(iout_t,position='append')
+ end if
+
+ tmplty=zero; tqcplty=zero ; ntot=0
+ tt=zero ; qctt=zero
+ if(nkeep > 0)then
+ mesage='current fit of temperature data, ranges in K $'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 't'
+ end do
+ call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_t,pflag)
+ do k=1,nsig
+ num(k)=nint(awork(5*nsig+k+100,i_t))
+ rat=zero ; rat3=zero
+ if(num(k) > 0) then
+ rat=awork(6*nsig+k+100,i_t)/real(num(k),r_kind)
+ rat3=awork(3*nsig+k+100,i_t)/real(num(k),r_kind)
+ end if
+ ntot=ntot+num(k); tmplty=tmplty+awork(6*nsig+k+100,i_t)
+ tqcplty=tqcplty+awork(3*nsig+k+100,i_t)
+ write(iout_t,240) 't',num(k),k,awork(6*nsig+k+100,i_t), &
+ awork(3*nsig+k+100,i_t),rat,rat3
+ end do
+ numgross=nint(awork(4,i_t))
+ numfailqc=nint(awork(21,i_t))
+ write(iout_t,925) 'temp',numgross,numfailqc
+ numlow = nint(awork(2,i_t))
+ numhgh = nint(awork(3,i_t))
+ write(iout_t,900) 't',numhgh,numlow
+ if(ntot > 0) then
+ tt=tmplty/ntot
+ qctt=tqcplty/ntot
end if
- ntot=ntot+num(k); tmplty=tmplty+awork(6*nsig+k+100,i_t)
- tqcplty=tqcplty+awork(3*nsig+k+100,i_t)
- write(iout_t,240) 't',num(k),k,awork(6*nsig+k+100,i_t), &
- awork(3*nsig+k+100,i_t),rat,rat3
- end do
- numgross=nint(awork(4,i_t))
- numfailqc=nint(awork(21,i_t))
- write(iout_t,925) 'temp',numgross,numfailqc
- numlow = nint(awork(2,i_t))
- numhgh = nint(awork(3,i_t))
- write(iout_t,900) 't',numhgh,numlow
- if(ntot > 0) then
- tt=tmplty/ntot
- qctt=tqcplty/ntot
end if
- end if
- write(iout_t,950) 't',jiter,nread,nkeep,ntot
- write(iout_t,951) 't',tmplty,tqcplty,tt,qctt
+ write(iout_t,950) 't',jiter,nread,nkeep,ntot
+ write(iout_t,951) 't',tmplty,tqcplty,tt,qctt
- close(iout_t)
+ close(iout_t)
+ end if
endif
! Summary report for doppler lidar winds
if(mype==mype_dw) then
- if(first)then
- open(iout_dw)
- else
- open(iout_dw,position='append')
- end if
-
- dwmplty=zero; dwqcplty=zero ; ntot=0
- tdw=zero ; qctdw=zero
nread=0
nkeep=0
do i=1,ndat
@@ -1120,56 +1155,58 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current vfit of lidar wind data, ranges in m/s$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'dw'
- end do
- call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_dw,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_dw)
+ else
+ open(iout_dw,position='append')
+ end if
+
+ dwmplty=zero; dwqcplty=zero ; ntot=0
+ tdw=zero ; qctdw=zero
+ if(nkeep > 0)then
+ mesage='current vfit of lidar wind data, ranges in m/s$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'dw'
+ end do
+ call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_dw,pflag)
- do k=1,nsig
- num(k)=nint(awork(k+5*nsig+100,i_dw))
- rat=zero
- rat3=zero
- if(num(k) > 0) then
- rat=awork(6*nsig+k+100,i_dw)/float(num(k))
- rat3=awork(3*nsig+k+100,i_dw)/float(num(k))
+ do k=1,nsig
+ num(k)=nint(awork(k+5*nsig+100,i_dw))
+ rat=zero
+ rat3=zero
+ if(num(k) > 0) then
+ rat=awork(6*nsig+k+100,i_dw)/real(num(k),r_kind)
+ rat3=awork(3*nsig+k+100,i_dw)/real(num(k),r_kind)
+ end if
+ ntot=ntot+num(k)
+ dwmplty=dwmplty+awork(6*nsig+k+100,i_dw)
+ dwqcplty=dwqcplty+awork(3*nsig+k+100,i_dw)
+ write(iout_dw,240) 'r',num(k),k,awork(6*nsig+k+100,i_dw), &
+ awork(3*nsig+k+100,i_dw),rat,rat3
+ end do
+ numgross=nint(awork(4,i_dw))
+ numfailqc=nint(awork(21,i_dw))
+ if(ntot > 0) then
+ tdw=dwmplty/real(ntot,r_kind)
+ qctdw=dwqcplty/real(ntot,r_kind)
end if
- ntot=ntot+num(k)
- dwmplty=dwmplty+awork(6*nsig+k+100,i_dw)
- dwqcplty=dwqcplty+awork(3*nsig+k+100,i_dw)
- write(iout_dw,240) 'r',num(k),k,awork(6*nsig+k+100,i_dw), &
- awork(3*nsig+k+100,i_dw),rat,rat3
- end do
- numgross=nint(awork(4,i_dw))
- numfailqc=nint(awork(21,i_dw))
- if(ntot > 0) then
- tdw=dwmplty/float(ntot)
- qctdw=dwqcplty/float(ntot)
- end if
- write(iout_dw,925) 'dw',numgross,numfailqc
- numlow = nint(awork(2,i_dw))
- numhgh = nint(awork(3,i_dw))
- write(iout_dw,900) 'dw',numhgh,numlow
- end if
+ write(iout_dw,925) 'dw',numgross,numfailqc
+ numlow = nint(awork(2,i_dw))
+ numhgh = nint(awork(3,i_dw))
+ write(iout_dw,900) 'dw',numhgh,numlow
+ end if
- write(iout_dw,950) 'dw',jiter,nread,nkeep,ntot
- write(iout_dw,951) 'dw',dwmplty,dwqcplty,tdw,qctdw
+ write(iout_dw,950) 'dw',jiter,nread,nkeep,ntot
+ write(iout_dw,951) 'dw',dwmplty,dwqcplty,tdw,qctdw
- close(iout_dw)
+ close(iout_dw)
+ end if
end if
! Summary report for radar radial winds
if(mype==mype_rw) then
- if(first)then
- open(iout_rw)
- else
- open(iout_rw,position='append')
- end if
-
- rwmplty=zero; rwqcplty=zero ; ntot=0
- trw=zero ; qctrw=zero
nread=0
nkeep=0
do i=1,ndat
@@ -1178,57 +1215,59 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current vfit of radar wind data, ranges in m/s$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'rw'
- end do
- call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_rw,pflag)
+ if(nread > 0)then
+ if(first)then
+ open(iout_rw)
+ else
+ open(iout_rw,position='append')
+ end if
- numgross=nint(awork(4,i_rw))
- numfailqc=nint(awork(21,i_rw))
- do k=1,nsig
- num(k)=nint(awork(k+5*nsig+100,i_rw))
- rat=zero
- rat3=zero
- if(num(k) > 0) then
- rat=awork(6*nsig+k+100,i_rw)/float(num(k))
- rat3=awork(3*nsig+k+100,i_rw)/float(num(k))
+ rwmplty=zero; rwqcplty=zero ; ntot=0
+ trw=zero ; qctrw=zero
+ if(nkeep > 0)then
+ mesage='current vfit of radar wind data, ranges in m/s$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'rw'
+ end do
+ call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_rw,pflag)
+
+ numgross=nint(awork(4,i_rw))
+ numfailqc=nint(awork(21,i_rw))
+ do k=1,nsig
+ num(k)=nint(awork(k+5*nsig+100,i_rw))
+ rat=zero
+ rat3=zero
+ if(num(k) > 0) then
+ rat=awork(6*nsig+k+100,i_rw)/real(num(k),r_kind)
+ rat3=awork(3*nsig+k+100,i_rw)/real(num(k),r_kind)
+ end if
+ ntot=ntot+num(k)
+ rwmplty=rwmplty+awork(6*nsig+k+100,i_rw)
+ rwqcplty=rwqcplty+awork(3*nsig+k+100,i_rw)
+ write(iout_rw,240) 'r',num(k),k,awork(6*nsig+k+100,i_rw), &
+ awork(3*nsig+k+100,i_rw),rat,rat3
+ end do
+ if(ntot > 0) then
+ trw=rwmplty/real(ntot,r_kind)
+ qctrw=rwqcplty/real(ntot,r_kind)
end if
- ntot=ntot+num(k)
- rwmplty=rwmplty+awork(6*nsig+k+100,i_rw)
- rwqcplty=rwqcplty+awork(3*nsig+k+100,i_rw)
- write(iout_rw,240) 'r',num(k),k,awork(6*nsig+k+100,i_rw), &
- awork(3*nsig+k+100,i_rw),rat,rat3
- end do
- if(ntot > 0) then
- trw=rwmplty/float(ntot)
- qctrw=rwqcplty/float(ntot)
- end if
- write(iout_rw,925) 'rw',numgross,numfailqc
- numlow = nint(awork(2,i_rw))
- numhgh = nint(awork(3,i_rw))
- nhitopo = nint(awork(5,i_rw))
- ntoodif = nint(awork(6,i_rw))
- write(iout_rw,900) 'rw',numhgh,numlow
- write(iout_rw,905) 'rw',nhitopo,ntoodif
- end if
- write(iout_rw,950) 'rw',jiter,nread,nkeep,ntot
- write(iout_rw,951) 'rw',rwmplty,rwqcplty,trw,qctrw
+ write(iout_rw,925) 'rw',numgross,numfailqc
+ numlow = nint(awork(2,i_rw))
+ numhgh = nint(awork(3,i_rw))
+ nhitopo = nint(awork(5,i_rw))
+ ntoodif = nint(awork(6,i_rw))
+ write(iout_rw,900) 'rw',numhgh,numlow
+ write(iout_rw,905) 'rw',nhitopo,ntoodif
+ end if
+ write(iout_rw,950) 'rw',jiter,nread,nkeep,ntot
+ write(iout_rw,951) 'rw',rwmplty,rwqcplty,trw,qctrw
- close(iout_rw)
+ close(iout_rw)
+ end if
end if
! Summary report for radar reflectivity
if(mype==mype_dbz) then
- if(first)then
- open(iout_dbz)
- else
- open(iout_dbz,position='append')
- end if
-
- dbzmplty=zero; dbzqcplty=zero ; ntot=0
- tdbz=zero ; qctdbz=zero
nread=0
nkeep=0
do i=1,ndat
@@ -1237,56 +1276,120 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current vfit of radar reflectivity data, ranges in dBZ$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'dbz'
- end do
- call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_dbz,pflag)
-
- numgross=nint(awork(4,i_dbz))
- numfailqc=nint(awork(21,i_dbz))
- do k=1,nsig
- num(k)=nint(awork(k+5*nsig+100,i_dbz))
- rat=zero
- rat3=zero
- if(num(k) > 0) then
- rat=awork(6*nsig+k+100,i_dbz)/float(num(k))
- rat3=awork(3*nsig+k+100,i_dbz)/float(num(k))
+ if(nread > 0)then
+ if(first)then
+ open(iout_dbz)
+ else
+ open(iout_dbz,position='append')
+ end if
+
+ dbzmplty=zero; dbzqcplty=zero ; ntot=0
+ tdbz=zero ; qctdbz=zero
+ if(nkeep > 0)then
+ mesage='current vfit of radar reflectivity data, ranges in dBZ$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'dbz'
+ end do
+ call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_dbz,pflag)
+
+ numgross=nint(awork(4,i_dbz))
+ numfailqc=nint(awork(21,i_dbz))
+ do k=1,nsig
+ num(k)=nint(awork(k+5*nsig+100,i_dbz))
+ rat=zero
+ rat3=zero
+ if(num(k) > 0) then
+ rat=awork(6*nsig+k+100,i_dbz)/real(num(k),r_kind)
+ rat3=awork(3*nsig+k+100,i_dbz)/real(num(k),r_kind)
+ end if
+ ntot=ntot+num(k)
+ dbzmplty=dbzmplty+awork(6*nsig+k+100,i_dbz)
+ dbzqcplty=dbzqcplty+awork(3*nsig+k+100,i_dbz)
+ write(iout_dbz,240) 'r',num(k),k,awork(6*nsig+k+100,i_dbz), &
+ awork(3*nsig+k+100,i_dbz),rat,rat3
+ end do
+ if(ntot > 0) then
+ tdbz=dbzmplty/real(ntot,r_kind)
+ qctdbz=dbzqcplty/real(ntot,r_kind)
end if
- ntot=ntot+num(k)
- dbzmplty=dbzmplty+awork(6*nsig+k+100,i_dbz)
- dbzqcplty=dbzqcplty+awork(3*nsig+k+100,i_dbz)
- write(iout_dbz,240) 'r',num(k),k,awork(6*nsig+k+100,i_dbz), &
- awork(3*nsig+k+100,i_dbz),rat,rat3
- end do
- if(ntot > 0) then
- tdbz=dbzmplty/float(ntot)
- qctdbz=dbzqcplty/float(ntot)
- end if
- write(iout_dbz,925) 'dbz',numgross,numfailqc
- numlow = nint(awork(2,i_dbz))
- numhgh = nint(awork(3,i_dbz))
- nhitopo = nint(awork(5,i_dbz))
- ntoodif = nint(awork(6,i_dbz))
- write(iout_dbz,900) 'dbz',numhgh,numlow
- write(iout_dbz,905) 'dbz',nhitopo,ntoodif
- end if
- write(iout_dbz,950) 'dbz',jiter,nread,nkeep,ntot
- write(iout_dbz,951) 'dbz',dbzmplty,dbzqcplty,tdbz,qctdbz
+ write(iout_dbz,925) 'dbz',numgross,numfailqc
+ numlow = nint(awork(2,i_dbz))
+ numhgh = nint(awork(3,i_dbz))
+ nhitopo = nint(awork(5,i_dbz))
+ ntoodif = nint(awork(6,i_dbz))
+ write(iout_dbz,900) 'dbz',numhgh,numlow
+ write(iout_dbz,905) 'dbz',nhitopo,ntoodif
+ end if
+ write(iout_dbz,950) 'dbz',jiter,nread,nkeep,ntot
+ write(iout_dbz,951) 'dbz',dbzmplty,dbzqcplty,tdbz,qctdbz
- close(iout_dbz)
+ close(iout_dbz)
+ end if
end if
- if(mype==mype_tcp) then
- if(first)then
- open(iout_tcp)
- else
- open(iout_tcp,position='append')
+! Summary report for flash extent density
+ if(mype==mype_fed) then
+ nread=0
+ nkeep=0
+ do i=1,ndat
+ if(dtype(i)== 'fed')then
+ nread=nread+ndata(i,2)
+ nkeep=nkeep+ndata(i,3)
+ end if
+ end do
+ if(nread > 0)then
+ if(first)then
+ open(iout_fed)
+ else
+ open(iout_fed,position='append')
+ end if
+
+ fedmplty=zero; fedqcplty=zero ; ntot=0
+ tfed=zero ; qctfed=zero
+ if(nkeep > 0)then
+ mesage='current vfit of flash extent density, ranges in flashes per minute$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'fed'
+ end do
+ call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_fed,pflag)
+
+ numgross=nint(awork(4,i_fed))
+ numfailqc=nint(awork(21,i_fed))
+ do k=1,nsig
+ num(k)=nint(awork(k+5*nsig+100,i_fed))
+ rat=zero
+ rat3=zero
+ if(num(k) > 0) then
+ rat=awork(6*nsig+k+100,i_fed)/real(num(k),r_kind)
+ rat3=awork(3*nsig+k+100,i_fed)/real(num(k),r_kind)
+ end if
+ ntot=ntot+num(k)
+ fedmplty=fedmplty+awork(6*nsig+k+100,i_fed)
+ fedqcplty=fedqcplty+awork(3*nsig+k+100,i_fed)
+ write(iout_fed,240) 'r',num(k),k,awork(6*nsig+k+100,i_fed), &
+ awork(3*nsig+k+100,i_fed),rat,rat3
+ end do
+ if(ntot > 0) then
+ tfed=fedmplty/real(ntot,r_kind)
+ qctfed=fedqcplty/real(ntot,r_kind)
+ end if
+ write(iout_fed,925) 'fed',numgross,numfailqc
+ numlow = nint(awork(2,i_fed))
+ numhgh = nint(awork(3,i_fed))
+ nhitopo = nint(awork(5,i_fed))
+ ntoodif = nint(awork(6,i_fed))
+ write(iout_fed,900) 'fed',numhgh,numlow
+ write(iout_fed,905) 'fed',nhitopo,ntoodif
+ end if
+ write(iout_fed,950) 'fed',jiter,nread,nkeep,ntot
+ write(iout_fed,951) 'fed',fedmplty,fedqcplty,tfed,qctfed
+
+ close(iout_fed)
end if
+ end if
+
- nump=nint(awork(5,i_tcp))
- pw=zero ; pw3=zero
+ if(mype==mype_tcp) then
nread=0
nkeep=0
do i=1,ndat
@@ -1295,39 +1398,41 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of surface pressure data, ranges in mb$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'tcp'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_tcp,pflag)
-
- numgross=nint(awork(6,i_tcp))
- numfailqc=nint(awork(21,i_tcp))
- write(iout_tcp,925) 'psfc',numgross,numfailqc
+ if(nread > 0)then
+ if(first)then
+ open(iout_tcp)
+ else
+ open(iout_tcp,position='append')
+ end if
- if(nump > 0)then
- pw=awork(4,i_tcp)/float(nump)
- pw3=awork(22,i_tcp)/float(nump)
+ nump=nint(awork(5,i_tcp))
+ pw=zero ; pw3=zero
+ if(nkeep > 0)then
+ mesage='current fit of surface pressure data, ranges in mb$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'tcp'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_tcp,pflag)
+
+ numgross=nint(awork(6,i_tcp))
+ numfailqc=nint(awork(21,i_tcp))
+ write(iout_tcp,925) 'psfc',numgross,numfailqc
+
+ if(nump > 0)then
+ pw=awork(4,i_tcp)/real(nump,r_kind)
+ pw3=awork(22,i_tcp)/real(nump,r_kind)
+ end if
end if
- end if
- write(iout_tcp,950) 'psfc',jiter,nread,nkeep,nump
- write(iout_tcp,951) 'psfc',awork(4,i_tcp),awork(22,i_tcp),pw,pw3
+ write(iout_tcp,950) 'psfc',jiter,nread,nkeep,nump
+ write(iout_tcp,951) 'psfc',awork(4,i_tcp),awork(22,i_tcp),pw,pw3
- close(iout_tcp)
+ close(iout_tcp)
+ end if
end if
! Summary report for lagrangian
if (mype==mype_lag)then
- if(first)then
- open(iout_lag)
- else
- open(iout_lag,position='append')
- end if
-
- tmplty=zero; tqcplty=zero ; ntot=0
- tt=zero ; qctt=zero
nread=0
nkeep=0
do i=1,ndat
@@ -1336,53 +1441,54 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of lagangian data, ranges in m $'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'lag'
- end do
- call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_lag,pflag)
- do k=1,nsig
- num(k)=nint(awork(6*nsig+k+100,i_lag))
- rat=zero ; rat3=zero
- if(num(k) > 0) then
- rat=awork(4*nsig+k+100,i_lag)/float(num(k))
- rat3=awork(3*nsig+k+100,i_lag)/float(num(k))
+ if(nread > 0)then
+ if(first)then
+ open(iout_lag)
+ else
+ open(iout_lag,position='append')
+ end if
+
+ tmplty=zero; tqcplty=zero ; ntot=0
+ tt=zero ; qctt=zero
+ if(nkeep > 0)then
+ mesage='current fit of lagangian data, ranges in m $'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'lag'
+ end do
+ call dtast(bwork,npres_print,pbot,ptop,mesage,jiter,iout_lag,pflag)
+ do k=1,nsig
+ num(k)=nint(awork(6*nsig+k+100,i_lag))
+ rat=zero ; rat3=zero
+ if(num(k) > 0) then
+ rat=awork(4*nsig+k+100,i_lag)/real(num(k),r_kind)
+ rat3=awork(3*nsig+k+100,i_lag)/real(num(k),r_kind)
+ end if
+ ntot=ntot+num(k); tmplty=tmplty+awork(4*nsig+k+100,i_lag)
+ tqcplty=tqcplty+awork(3*nsig+k+100,i_lag)
+ write(iout_lag,240) 'lag',num(k),k,awork(4*nsig+k+100,i_lag), &
+ awork(3*nsig+k+100,i_lag),rat,rat3
+ end do
+ numgross=nint(awork(4,i_lag))
+ numfailqc=nint(awork(21,i_lag))
+ write(iout_lag,925) 'lag',numgross,numfailqc
+ ! numlow = nint(awork(2,i_t))
+ ! numhgh = nint(awork(3,i_t))
+ ! write(iout_lag,900) 't',numhgh,numlow
+ if(ntot > 0) then
+ tt=tmplty/ntot
+ qctt=tqcplty/ntot
end if
- ntot=ntot+num(k); tmplty=tmplty+awork(4*nsig+k+100,i_lag)
- tqcplty=tqcplty+awork(3*nsig+k+100,i_lag)
- write(iout_lag,240) 'lag',num(k),k,awork(4*nsig+k+100,i_lag), &
- awork(3*nsig+k+100,i_lag),rat,rat3
- end do
- numgross=nint(awork(4,i_lag))
- numfailqc=nint(awork(21,i_lag))
- write(iout_lag,925) 'lag',numgross,numfailqc
- ! numlow = nint(awork(2,i_t))
- ! numhgh = nint(awork(3,i_t))
- ! write(iout_lag,900) 't',numhgh,numlow
- if(ntot > 0) then
- tt=tmplty/ntot
- qctt=tqcplty/ntot
end if
- end if
- write(iout_lag,950) 'lag',jiter,nread,nkeep,ntot
- write(iout_lag,951) 'lag',tmplty,tqcplty,tt,qctt
+ write(iout_lag,950) 'lag',jiter,nread,nkeep,ntot
+ write(iout_lag,951) 'lag',tmplty,tqcplty,tt,qctt
- close(iout_lag)
+ close(iout_lag)
+ end if
endif
! Summary report for solid-water content path
if(mype==mype_swcp) then
- if(first)then
- open(iout_swcp)
- else
- open(iout_swcp,position='append')
- end if
-
- nsuperp=nint(awork(4,i_swcp))
-
- tswcp=zero ; tswcp3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -1391,42 +1497,44 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of solid-water content path, ranges in kg/m^2$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'swcp'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_swcp,pflag)
-
- numgrsswcp=nint(awork(6,i_swcp))
- numfailqc=nint(awork(21,i_swcp))
- grsmlt=three
- tswcp=zero
- tswcp3=zero
- if(nsuperp > 0)then
- tswcp=awork(5,i_swcp)/nsuperp
- tswcp3=awork(22,i_swcp)/nsuperp
- end if
- write(iout_swcp,925) 'swcp',numgrsswcp,numfailqc
- write(iout_swcp,975) grsmlt,'swcp',awork(7,i_swcp)
- end if
- write(iout_swcp,950) 'swcp',jiter,nread,nkeep,nsuperp
- write(iout_swcp,951) 'swcp',awork(5,i_swcp),awork(22,i_swcp),tswcp,tswcp3
+ if(nread > 0)then
+ if(first)then
+ open(iout_swcp)
+ else
+ open(iout_swcp,position='append')
+ end if
+
+ nsuperp=nint(awork(4,i_swcp))
+
+ tswcp=zero ; tswcp3=zero
+ if(nkeep > 0)then
+ mesage='current fit of solid-water content path, ranges in kg/m^2$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'swcp'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_swcp,pflag)
+
+ numgrsswcp=nint(awork(6,i_swcp))
+ numfailqc=nint(awork(21,i_swcp))
+ grsmlt=three
+ tswcp=zero
+ tswcp3=zero
+ if(nsuperp > 0)then
+ tswcp=awork(5,i_swcp)/nsuperp
+ tswcp3=awork(22,i_swcp)/nsuperp
+ end if
+ write(iout_swcp,925) 'swcp',numgrsswcp,numfailqc
+ write(iout_swcp,975) grsmlt,'swcp',awork(7,i_swcp)
+ end if
+ write(iout_swcp,950) 'swcp',jiter,nread,nkeep,nsuperp
+ write(iout_swcp,951) 'swcp',awork(5,i_swcp),awork(22,i_swcp),tswcp,tswcp3
- close(iout_swcp)
+ close(iout_swcp)
+ end if
end if
! Summary report for liquid-water content path
if(mype==mype_lwcp) then
- if(first)then
- open(iout_lwcp)
- else
- open(iout_lwcp,position='append')
- end if
-
- nsuperp=nint(awork(4,i_lwcp))
-
- tlwcp=zero ; tlwcp3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -1435,29 +1543,40 @@ subroutine statsconv(mype,&
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of liquid-water content path, ranges in kg/m^2$'
- do j=1,nconvtype
- pflag(j)=trim(ioctype(j)) == 'lwcp'
- end do
- call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_lwcp,pflag)
-
- numgrslwcp=nint(awork(6,i_lwcp))
- numfailqc=nint(awork(21,i_lwcp))
- grsmlt=three
- tlwcp=zero
- tlwcp3=zero
- if(nsuperp > 0)then
- tlwcp=awork(5,i_lwcp)/nsuperp
- tlwcp3=awork(22,i_lwcp)/nsuperp
- end if
- write(iout_lwcp,925) 'lwcp',numgrslwcp,numfailqc
- write(iout_lwcp,975) grsmlt,'lwcp',awork(7,i_lwcp)
- end if
- write(iout_lwcp,950) 'lwcp',jiter,nread,nkeep,nsuperp
- write(iout_lwcp,951) 'lwcp',awork(5,i_lwcp),awork(22,i_lwcp),tlwcp,tlwcp3
+ if(nread > 0)then
+ if(first)then
+ open(iout_lwcp)
+ else
+ open(iout_lwcp,position='append')
+ end if
- close(iout_lwcp)
+ nsuperp=nint(awork(4,i_lwcp))
+
+ tlwcp=zero ; tlwcp3=zero
+ if(nkeep > 0)then
+ mesage='current fit of liquid-water content path, ranges in kg/m^2$'
+ do j=1,nconvtype
+ pflag(j)=trim(ioctype(j)) == 'lwcp'
+ end do
+ call dtast(bwork,1,pbotall,ptopall,mesage,jiter,iout_lwcp,pflag)
+
+ numgrslwcp=nint(awork(6,i_lwcp))
+ numfailqc=nint(awork(21,i_lwcp))
+ grsmlt=three
+ tlwcp=zero
+ tlwcp3=zero
+ if(nsuperp > 0)then
+ tlwcp=awork(5,i_lwcp)/nsuperp
+ tlwcp3=awork(22,i_lwcp)/nsuperp
+ end if
+ write(iout_lwcp,925) 'lwcp',numgrslwcp,numfailqc
+ write(iout_lwcp,975) grsmlt,'lwcp',awork(7,i_lwcp)
+ end if
+ write(iout_lwcp,950) 'lwcp',jiter,nread,nkeep,nsuperp
+ write(iout_lwcp,951) 'lwcp',awork(5,i_lwcp),awork(22,i_lwcp),tlwcp,tlwcp3
+
+ close(iout_lwcp)
+ end if
end if
@@ -1472,7 +1591,7 @@ subroutine statsconv(mype,&
' number with abs(guess topography-station elevation) > 200m = ',i8)
920 format(a44,i7)
924 format(a50)
-925 format(' number of ',a5,' obs that failed gross test = ',I5,' nonlin qc test = ',I5)
+925 format(' number of ',a7,' obs that failed gross test = ',I6,' nonlin qc test = ',I6)
949 format(' number of ',a5,' obs = ',i7,' pen= ',e25.18,' cpen= ',g13.6)
950 format(' type ',a7,' jiter ',i3,' nread ',i9,' nkeep ',i7,' num ',i7)
951 format(' type ',a7,' pen= ',e25.18,' qcpen= ',e25.18,' r= ',g13.6,' qcr= ',g13.6)
diff --git a/src/gsi/statslight.f90 b/src/gsi/statslight.f90
index ffcdef6a0a..7f8e7c8349 100644
--- a/src/gsi/statslight.f90
+++ b/src/gsi/statslight.f90
@@ -56,31 +56,14 @@ subroutine statslight(mype,i_light,bwork,awork,i_ref,ndata)
real(r_kind) grsmlt,tlight
real(r_kind) tlight3
- real(r_kind),dimension(1):: pbotall,ptopall
logical,dimension(nlighttype):: pflag
!*********************************************************************************
-! Initialize constants and variables.
- ptopall(1)=zero; pbotall(1)=2000.0_r_kind
-
-
-! Generate summary statistics
-
- pflag=.FALSE.
-
-! Summary report for lightning flash rate
+! Generate statistics Summary report for lightning flash rate
if(mype==mype_light) then
- if(first)then
- open(iout_light)
- else
- open(iout_light,position='append')
- end if
-
- nsuperl=nint(awork(4,i_light))
- tlight=zero ; tlight3=zero
nread=0
nkeep=0
do i=1,ndat
@@ -89,29 +72,40 @@ subroutine statslight(mype,i_light,bwork,awork,i_ref,ndata)
nkeep=nkeep+ndata(i,3)
end if
end do
- if(nkeep > 0)then
- mesage='current fit of lightning data, range in #hits km-2 hr-1$'
- do j=1,nlighttype
- pflag(j)=trim(nulight(j)) == 'light'
- enddo
-
- call dtast(bwork,1,pbot,ptop,mesage,jiter,iout_light,pflag)
+ if(nread > 0)then
+ pflag=.FALSE.
+ if(first)then
+ open(iout_light)
+ else
+ open(iout_light,position='append')
+ end if
- numgrslight=nint(awork(6,i_light))
- numfailqc=nint(awork(21,i_light))
- grsmlt=three
- tlight=zero
- if(nsuperl > 0)then
- tlight=awork(5,i_light)/nsuperl
- tlight3=awork(22,i_light)/nsuperl
+ nsuperl=nint(awork(4,i_light))
+ tlight=zero ; tlight3=zero
+ if(nkeep > 0)then
+ mesage='current fit of lightning data, range in #hits km-2 hr-1$'
+ do j=1,nlighttype
+ pflag(j)=trim(nulight(j)) == 'light'
+ enddo
+
+ call dtast(bwork,1,pbot,ptop,mesage,jiter,iout_light,pflag)
+
+ numgrslight=nint(awork(6,i_light))
+ numfailqc=nint(awork(21,i_light))
+ grsmlt=three
+ tlight=zero
+ if(nsuperl > 0)then
+ tlight=awork(5,i_light)/nsuperl
+ tlight3=awork(22,i_light)/nsuperl
+ end if
+ write(iout_light,925) 'light',numgrslight,numfailqc
+ write(iout_light,975) grsmlt,'light',awork(7,i_light)
end if
- write(iout_light,925) 'light',numgrslight,numfailqc
- write(iout_light,975) grsmlt,'light',awork(7,i_light)
- end if
- write(iout_light,950) 'light',jiter,nread,nkeep,nsuperl
- write(iout_light,951) 'light',awork(5,i_light),awork(22,i_light),tlight,tlight3
+ write(iout_light,950) 'light',jiter,nread,nkeep,nsuperl
+ write(iout_light,951) 'light',awork(5,i_light),awork(22,i_light),tlight,tlight3
- close(iout_light)
+ close(iout_light)
+ end if
end if
diff --git a/src/gsi/statsoz.f90 b/src/gsi/statsoz.f90
index 069082d6b7..fb5f536914 100644
--- a/src/gsi/statsoz.f90
+++ b/src/gsi/statsoz.f90
@@ -101,7 +101,7 @@ subroutine statsoz(stats_oz,ndata)
if (iasim > 0) then
svar = error_oz(i)
if (iuse_oz(i)/=1) svar = -svar
- rsum = one/float(iasim)
+ rsum = one/real(iasim,r_kind)
icerr = nint(stats_oz(2,i))
do j=3,6 ! j=3=obs-mod(w_biascor)
! j=4=(obs-mod(w_biascor))**2
@@ -127,7 +127,7 @@ subroutine statsoz(stats_oz,ndata)
do i=1,ndat
if (idisplay(i)) then
cpen=zero
- if (icount_asim(i)>0) cpen=rpenal(i)/float(icount_asim(i))
+ if (icount_asim(i)>0) cpen=rpenal(i)/real(icount_asim(i),r_kind)
write(iout_oz,1115) jiter,dplat(i),dtype(i),ndata(i,2), &
ndata(i,3),icount_asim(i),rpenal(i),cpen,qcpenal(i),iqccount_asim(i)
endif
diff --git a/src/gsi/statspcp.f90 b/src/gsi/statspcp.f90
index e16f6dfbe5..ad79aed67d 100644
--- a/src/gsi/statspcp.f90
+++ b/src/gsi/statspcp.f90
@@ -210,7 +210,7 @@ subroutine statspcp(aivals,ndata)
if (isum > 0 .and. display(is)) then
rpen(is) = aivals(15,is)
qcpen(is) = aivals(39,is)
- rsum = one/float(isum)
+ rsum = one/real(isum,r_kind)
icerr = nint(aivals(12,is))
do j=13,16
aivals(j,is)=aivals(j,is)*rsum
diff --git a/src/gsi/statsrad.f90 b/src/gsi/statsrad.f90
index c6a993092c..d42a53f7d6 100644
--- a/src/gsi/statsrad.f90
+++ b/src/gsi/statsrad.f90
@@ -120,7 +120,7 @@ subroutine statsrad(aivals,stats,ndata)
if (iasim > 0) then
svar = varch(i)
if (iuse_rad(i) < 1) svar=-svar
- rsum = one/float(iasim)
+ rsum = one/real(iasim,r_kind)
icerr = nint(stats(2,i))
do j=3,6 ! j=3=obs-mod(w_biascor)
! j=4=(obs-mod(w_biascor))**2
@@ -142,7 +142,7 @@ subroutine statsrad(aivals,stats,ndata)
! Write obs count to runtime output file
write(iout_rad,1109)
do i=1,ndat
- if(idisplay(i))then
+ if(idisplay(i) .and. ndata(i,2) > 0)then
iobs2 = nint(aivals(38,i))
qcpenal = aivals(39,i)
rpenal = aivals(40,i)
@@ -162,9 +162,9 @@ subroutine statsrad(aivals,stats,ndata)
2012 format(12x,A7,5x,8(a7,1x))
2999 format(' Illegal satellite type ')
1102 format(1x,i4,i5,1x,a16,2i7,1x,f10.3,1x,6(f11.7,1x))
-1109 format(t5,'it',t13,'satellite',t23,'instrument',t38, &
- '# read',t49,'# keep',t59,'# assim',&
- t68,'penalty',t81,'qcpnlty',t95,'cpen',t105,'qccpen')
+1109 format(t5,'it',t13,'satellite',t23,'instrument',t40, &
+ '# read',t53,'# keep',t65,'# assim',&
+ t75,'penalty',t88,'qcpnlty',t104,'cpen',t115,'qccpen')
1115 format('o-g',1x,i2.2,1x,'rad',2x,2A10,2x,3(i11,2x),4(g12.5,1x))
! Close output unit
diff --git a/src/gsi/stpcalc.f90 b/src/gsi/stpcalc.f90
index 80fac64d61..34030763db 100644
--- a/src/gsi/stpcalc.f90
+++ b/src/gsi/stpcalc.f90
@@ -226,17 +226,19 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
use stpjcmod, only: stplimq,stplimg,stplimv,stplimp,stplimw10m,&
stplimhowv,stplimcldch,stpjcdfi,stpjcpdry,stpliml,stplimqc
use bias_predictors, only: predictors
- use control_vectors, only: control_vector,qdot_prod_sub,cvars2d,cvars3d
+ use control_vectors, only: control_vector,qdot_prod_sub
+ use state_vectors, only: qgpresent,qspresent,qrpresent,qipresent,qlpresent
+ use state_vectors, only: cldchpresent,lcbaspresent,howvpresent,wspd10mpresent,pblhpresent,vispresent,gustpresent
use state_vectors, only: allocate_state,deallocate_state
use gsi_bundlemod, only: gsi_bundle
use gsi_bundlemod, only: gsi_bundlegetpointer
use gsi_bundlemod, only: assignment(=)
use guess_grids, only: ntguessig,nfldsig
use mpl_allreducemod, only: mpl_allreduce
- use mpeu_util, only: getindex
use timermod, only: timer_ini,timer_fnl
use stpjomod, only: stpjo
use gsi_io, only: verbose
+ use gridmod, only: minmype
implicit none
! Declare passed variables
@@ -261,25 +263,24 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
real(r_quad),parameter:: one_tenth_quad = 0.1_r_quad
! Declare local variables
- integer(i_kind) i,j,mm1,ii,iis,ibin,ipenloc,it
+ integer(i_kind) i,j,mm1,ii,final_ii,ibin,ipenloc,it
integer(i_kind) istp_use,nstep,nsteptot,kprt
real(r_quad),dimension(4,ipen):: pbc
real(r_quad),dimension(4,nobs_type):: pbcjo
real(r_quad),dimension(4,nobs_type,nobs_bins):: pbcjoi
- real(r_quad),dimension(4,nobs_bins):: pbcqmin,pbcqmax
+ real(r_quad),dimension(4):: pbcqmin,pbcqmax
real(r_quad),dimension(4,nobs_bins):: pbcql,pbcqi,pbcqr,pbcqs,pbcqg
real(r_quad),dimension(ipen):: pen_est
real(r_quad),dimension(3,ipenlin):: pstart
real(r_quad) bx,cx,ccoef,bcoef,dels,sges1,sgesj
real(r_quad),dimension(0:istp_iter):: stp
real(r_kind),dimension(istp_iter):: stprat
- real(r_quad),dimension(ipen):: bsum,csum,bsum_save,csum_save,pen_save
+ real(r_quad),dimension(ipen):: bsum,csum
real(r_quad),dimension(ipen,nobs_bins):: pj
real(r_kind) delpen
real(r_kind) outpensave
real(r_kind),dimension(4)::sges
real(r_kind),dimension(ioutpen):: outpen,outstp
- logical :: cxterm,change_dels,ifound
logical :: print_verbose,pjcalc
@@ -290,7 +291,6 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
! Initialize variable
print_verbose=.false.
if(verbose)print_verbose=.true.
- cxterm=.false.
mm1=mype+1
stp(0)=stpinout
outpen = zero
@@ -299,6 +299,7 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
kprt=3
pjcalc=.false.
pj=zero_quad
+ final_ii=1
! Begin calculating contributions to penalty and stepsize for various terms
!
@@ -387,10 +388,10 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
! there, if one has to know or to reference them explicitly.
pstart=zero_quad
- pbc=zero_quad
if(iter == 0 .and. kprt >= 2)pjcalc=.true.
+
! penalty, b and c for background terms
pstart(1,1) = qdot_prod_sub(xhatsave,yhatsave)
@@ -426,11 +427,10 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
dels = one_tenth_quad
stepsize: do ii=1,istp_iter
+ pbc=zero_quad
pjcalc=.false.
if(iter == 0 .and. kprt >= 2 .and. ii == 1)pjcalc=.true.
- iis=ii
! Delta stepsize
- change_dels=.true.
sges(1)= stp(ii-1)
sges(2)=(one_quad-dels)*stp(ii-1)
@@ -448,7 +448,6 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
end if
! Calculate penalty values for linear terms
-
do i=1,ipenlin
sges1=real(sges(1),r_quad)
pbc(1,i)=pstart(1,i)-(2.0_r_quad*pstart(2,i)-pstart(3,i)*sges1)*sges1
@@ -462,6 +461,8 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
! penalties for moisture constraint
if(.not. ltlint)then
+!$omp parallel sections
+!$omp section
if(.not.ljc4tlevs) then
call stplimq(dval(ibin_anl),sval(ibin_anl),sges,pbc(1,4),pbc(1,5),nstep,ntguessig)
if(pjcalc)then
@@ -475,216 +476,226 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
else
it=ibin
end if
- call stplimq(dval(ibin),sval(ibin),sges,pbcqmin(1,ibin),pbcqmax(1,ibin),nstep,it)
- end do
- pbc(:,4)=zero_quad
- pbc(:,5)=zero_quad
- do ibin=1,nobs_bins
+ call stplimq(dval(ibin),sval(ibin),sges,pbcqmin,pbcqmax,nstep,it)
do j=1,nstep
- pbc(j,4) = pbc(j,4)+pbcqmin(j,ibin)
- pbc(j,5) = pbc(j,5)+pbcqmax(j,ibin)
+ pbc(j,4) = pbc(j,4)+pbcqmin(j)
+ pbc(j,5) = pbc(j,5)+pbcqmax(j)
end do
+ if(pjcalc)then
+ pj(4,ibin)=pj(4,ibin)+pbcqmin(1)+pbcqmin(ipenloc)
+ pj(5,ibin)=pj(5,ibin)+pbcqmax(1)+pbcqmax(ipenloc)
+ end if
end do
- if(pjcalc)then
- do ibin=1,nobs_bins
- pj(4,ibin)=pj(4,ibin)+pbcqmin(1,ibin)+pbcqmin(ipenloc,ibin)
- pj(5,ibin)=pj(5,ibin)+pbcqmax(1,ibin)+pbcqmax(ipenloc,ibin)
- end do
- end if
end if
+!$omp section
! penalties for gust constraint
- if(getindex(cvars2d,'gust')>0) &
- call stplimg(dval(1),sval(1),sges,pbc(1,6),nstep)
- if(pjcalc)pj(6,1)=pbc(1,6)+pbc(ipenloc,6)
+ if(gustpresent) then
+ call stplimg(dval(1),sval(1),sges,pbc(1,6),nstep)
+ if(pjcalc)pj(6,1)=pbc(1,6)+pbc(ipenloc,6)
+ end if
+!$omp section
! penalties for vis constraint
- if(getindex(cvars2d,'vis')>0) &
- call stplimv(dval(1),sval(1),sges,pbc(1,7),nstep)
- if(pjcalc)pj(7,1)=pbc(1,7)+pbc(ipenloc,7)
+ if(vispresent) then
+ call stplimv(dval(1),sval(1),sges,pbc(1,7),nstep)
+ if(pjcalc)pj(7,1)=pbc(1,7)+pbc(ipenloc,7)
+ end if
! penalties for pblh constraint
- if(getindex(cvars2d,'pblh')>0) &
- call stplimp(dval(1),sval(1),sges,pbc(1,8),nstep)
- if(pjcalc)pj(8,1)=pbc(1,8)+pbc(ipenloc,8)
+!$omp section
+ if(pblhpresent) then
+ call stplimp(dval(1),sval(1),sges,pbc(1,8),nstep)
+ if(pjcalc)pj(8,1)=pbc(1,8)+pbc(ipenloc,8)
+ end if
! penalties for wspd10m constraint
- if(getindex(cvars2d,'wspd10m')>0) &
- call stplimw10m(dval(1),sval(1),sges,pbc(1,9),nstep)
- if(pjcalc)pj(9,1)=pbc(1,9)+pbc(ipenloc,9)
+!$omp section
+ if(wspd10mpresent) then
+ call stplimw10m(dval(1),sval(1),sges,pbc(1,9),nstep)
+ if(pjcalc)pj(9,1)=pbc(1,9)+pbc(ipenloc,9)
+ end if
! penalties for howv constraint
- if(getindex(cvars2d,'howv')>0) &
- call stplimhowv(dval(1),sval(1),sges,pbc(1,10),nstep)
- if(pjcalc)pj(10,1)=pbc(1,10)+pbc(ipenloc,10)
+!$omp section
+ if(howvpresent) then
+ call stplimhowv(dval(1),sval(1),sges,pbc(1,10),nstep)
+ if(pjcalc)pj(10,1)=pbc(1,10)+pbc(ipenloc,10)
+ end if
! penalties for lcbas constraint
- if(getindex(cvars2d,'lcbas')>0) &
- call stpliml(dval(1),sval(1),sges,pbc(1,11),nstep)
- if(pjcalc)pj(11,1)=pbc(1,11)+pbc(ipenloc,11)
+!$omp section
+ if(lcbaspresent) then
+ call stpliml(dval(1),sval(1),sges,pbc(1,11),nstep)
+ if(pjcalc)pj(11,1)=pbc(1,11)+pbc(ipenloc,11)
+ end if
! penalties for cldch constraint
- if(getindex(cvars2d,'cldch')>0) &
- call stplimcldch(dval(1),sval(1),sges,pbc(1,12),nstep)
- if(pjcalc)pj(12,1)=pbc(1,12)+pbc(ipenloc,12)
-
- if (ljclimqc) then
- if (getindex(cvars3d,'ql')>0) then
- if(.not.ljc4tlevs) then
- call stplimqc(dval(ibin_anl),sval(ibin_anl),sges,pbc(1,13),nstep,ntguessig,'ql')
- if(pjcalc) pj(13,1)=pbc(1,13)+pbc(ipenloc,13)
- else
- do ibin=1,nobs_bins
- if (nobs_bins /= nfldsig) then
- it=ntguessig
- else
- it=ibin
- end if
- call stplimqc(dval(ibin),sval(ibin),sges,pbcql(1,ibin),nstep,it,'ql')
- end do
- pbc(:,13)=zero_quad
- do ibin=1,nobs_bins
- do j=1,nstep
- pbc(j,13) = pbc(j,13)+pbcql(j,ibin)
- end do
- end do
- if(pjcalc)then
- do ibin=1,nobs_bins
- pj(13,ibin)=pj(13,ibin)+pbcql(1,ibin)+pbcql(ipenloc,ibin)
- end do
- end if
- end if
+!$omp section
+ if(cldchpresent) then
+ call stplimcldch(dval(1),sval(1),sges,pbc(1,12),nstep)
+ if(pjcalc)pj(12,1)=pbc(1,12)+pbc(ipenloc,12)
+ end if
+
+! if (ljclimqc) then
+!$omp section
+ if (qlpresent .and. ljclimqc ) then
+ if(.not.ljc4tlevs) then
+ call stplimqc(dval(ibin_anl),sval(ibin_anl),sges,pbc(1,13),nstep,ntguessig,'ql')
+ if(pjcalc) pj(13,1)=pbc(1,13)+pbc(ipenloc,13)
+ else
+ do ibin=1,nobs_bins
+ if (nobs_bins /= nfldsig) then
+ it=ntguessig
+ else
+ it=ibin
+ end if
+ call stplimqc(dval(ibin),sval(ibin),sges,pbcql(1,ibin),nstep,it,'ql')
+ end do
+ do ibin=1,nobs_bins
+ do j=1,nstep
+ pbc(j,13) = pbc(j,13)+pbcql(j,ibin)
+ end do
+ end do
+ if(pjcalc)then
+ do ibin=1,nobs_bins
+ pj(13,ibin)=pj(13,ibin)+pbcql(1,ibin)+pbcql(ipenloc,ibin)
+ end do
+ end if
end if
- if (getindex(cvars3d,'qi')>0) then
- if(.not.ljc4tlevs) then
- call stplimqc(dval(ibin_anl),sval(ibin_anl),sges,pbc(1,14),nstep,ntguessig,'qi')
- if(pjcalc) pj(14,1)=pbc(1,14)+pbc(ipenloc,14)
- else
- do ibin=1,nobs_bins
- if (nobs_bins /= nfldsig) then
- it=ntguessig
- else
- it=ibin
- end if
- call stplimqc(dval(ibin),sval(ibin),sges,pbcqi(1,ibin),nstep,it,'qi')
- end do
- pbc(:,14)=zero_quad
- do ibin=1,nobs_bins
- do j=1,nstep
- pbc(j,14) = pbc(j,14)+pbcqi(j,ibin)
- end do
- end do
- if(pjcalc)then
- do ibin=1,nobs_bins
- pj(14,ibin)=pj(14,ibin)+pbcqi(1,ibin)+pbcqi(ipenloc,ibin)
- end do
- end if
- end if
+ end if
+!$omp section
+ if (qipresent .and. ljclimqc ) then
+ if(.not.ljc4tlevs) then
+ call stplimqc(dval(ibin_anl),sval(ibin_anl),sges,pbc(1,14),nstep,ntguessig,'qi')
+ if(pjcalc) pj(14,1)=pbc(1,14)+pbc(ipenloc,14)
+ else
+ do ibin=1,nobs_bins
+ if (nobs_bins /= nfldsig) then
+ it=ntguessig
+ else
+ it=ibin
+ end if
+ call stplimqc(dval(ibin),sval(ibin),sges,pbcqi(1,ibin),nstep,it,'qi')
+ end do
+ do ibin=1,nobs_bins
+ do j=1,nstep
+ pbc(j,14) = pbc(j,14)+pbcqi(j,ibin)
+ end do
+ end do
+ if(pjcalc)then
+ do ibin=1,nobs_bins
+ pj(14,ibin)=pj(14,ibin)+pbcqi(1,ibin)+pbcqi(ipenloc,ibin)
+ end do
+ end if
end if
- if (getindex(cvars3d,'qr')>0) then
- if(.not.ljc4tlevs) then
- call stplimqc(dval(ibin_anl),sval(ibin_anl),sges,pbc(1,15),nstep,ntguessig,'qr')
- if(pjcalc) pj(15,1)=pbc(1,15)+pbc(ipenloc,15)
- else
- do ibin=1,nobs_bins
- if (nobs_bins /= nfldsig) then
- it=ntguessig
- else
- it=ibin
- end if
- call stplimqc(dval(ibin),sval(ibin),sges,pbcqr(1,ibin),nstep,it,'qr')
- end do
- pbc(:,15)=zero_quad
- do ibin=1,nobs_bins
- do j=1,nstep
- pbc(j,15) = pbc(j,15)+pbcqr(j,ibin)
- end do
- end do
- if(pjcalc)then
- do ibin=1,nobs_bins
- pj(15,ibin)=pj(15,ibin)+pbcqr(1,ibin)+pbcqr(ipenloc,ibin)
- end do
- end if
- end if
+ end if
+!$omp section
+ if (qrpresent .and. ljclimqc ) then
+ if(.not.ljc4tlevs) then
+ call stplimqc(dval(ibin_anl),sval(ibin_anl),sges,pbc(1,15),nstep,ntguessig,'qr')
+ if(pjcalc) pj(15,1)=pbc(1,15)+pbc(ipenloc,15)
+ else
+ do ibin=1,nobs_bins
+ if (nobs_bins /= nfldsig) then
+ it=ntguessig
+ else
+ it=ibin
+ end if
+ call stplimqc(dval(ibin),sval(ibin),sges,pbcqr(1,ibin),nstep,it,'qr')
+ end do
+ do ibin=1,nobs_bins
+ do j=1,nstep
+ pbc(j,15) = pbc(j,15)+pbcqr(j,ibin)
+ end do
+ end do
+ if(pjcalc)then
+ do ibin=1,nobs_bins
+ pj(15,ibin)=pj(15,ibin)+pbcqr(1,ibin)+pbcqr(ipenloc,ibin)
+ end do
+ end if
end if
- if (getindex(cvars3d,'qs')>0) then
- if(.not.ljc4tlevs) then
- call stplimqc(dval(ibin_anl),sval(ibin_anl),sges,pbc(1,16),nstep,ntguessig,'qs')
- if(pjcalc) pj(16,1)=pbc(1,16)+pbc(ipenloc,16)
- else
- do ibin=1,nobs_bins
- if (nobs_bins /= nfldsig) then
- it=ntguessig
- else
- it=ibin
- end if
- call stplimqc(dval(ibin),sval(ibin),sges,pbcqs(1,ibin),nstep,it,'qs')
- end do
- pbc(:,16)=zero_quad
- do ibin=1,nobs_bins
- do j=1,nstep
- pbc(j,16) = pbc(j,16)+pbcqs(j,ibin)
- end do
- end do
- if(pjcalc)then
- do ibin=1,nobs_bins
- pj(16,ibin)=pj(16,ibin)+pbcqs(1,ibin)+pbcqs(ipenloc,ibin)
- end do
- end if
- end if
+ end if
+!$omp section
+ if (qspresent .and. ljclimqc ) then
+ if(.not.ljc4tlevs) then
+ call stplimqc(dval(ibin_anl),sval(ibin_anl),sges,pbc(1,16),nstep,ntguessig,'qs')
+ if(pjcalc) pj(16,1)=pbc(1,16)+pbc(ipenloc,16)
+ else
+ do ibin=1,nobs_bins
+ if (nobs_bins /= nfldsig) then
+ it=ntguessig
+ else
+ it=ibin
+ end if
+ call stplimqc(dval(ibin),sval(ibin),sges,pbcqs(1,ibin),nstep,it,'qs')
+ end do
+ do ibin=1,nobs_bins
+ do j=1,nstep
+ pbc(j,16) = pbc(j,16)+pbcqs(j,ibin)
+ end do
+ end do
+ if(pjcalc)then
+ do ibin=1,nobs_bins
+ pj(16,ibin)=pj(16,ibin)+pbcqs(1,ibin)+pbcqs(ipenloc,ibin)
+ end do
+ end if
end if
- if (getindex(cvars3d,'qg')>0) then
- if(.not.ljc4tlevs) then
- call stplimqc(dval(ibin_anl),sval(ibin_anl),sges,pbc(1,17),nstep,ntguessig,'qg')
- if(pjcalc) pj(17,1)=pbc(1,17)+pbc(ipenloc,17)
- else
- do ibin=1,nobs_bins
- if (nobs_bins /= nfldsig) then
- it=ntguessig
- else
- it=ibin
- end if
- call stplimqc(dval(ibin),sval(ibin),sges,pbcqg(1,ibin),nstep,it,'qg')
- end do
- pbc(:,17)=zero_quad
- do ibin=1,nobs_bins
- do j=1,nstep
- pbc(j,17) = pbc(j,17)+pbcqg(j,ibin)
- end do
- end do
- if(pjcalc)then
- do ibin=1,nobs_bins
- pj(17,ibin)=pj(17,ibin)+pbcqg(1,ibin)+pbcqg(ipenloc,ibin)
- end do
- end if
- end if
+ end if
+!$omp section
+ if (qgpresent .and. ljclimqc ) then
+ if(.not.ljc4tlevs) then
+ call stplimqc(dval(ibin_anl),sval(ibin_anl),sges,pbc(1,17),nstep,ntguessig,'qg')
+ if(pjcalc) pj(17,1)=pbc(1,17)+pbc(ipenloc,17)
+ else
+ do ibin=1,nobs_bins
+ if (nobs_bins /= nfldsig) then
+ it=ntguessig
+ else
+ it=ibin
+ end if
+ call stplimqc(dval(ibin),sval(ibin),sges,pbcqg(1,ibin),nstep,it,'qg')
+ end do
+ do ibin=1,nobs_bins
+ do j=1,nstep
+ pbc(j,17) = pbc(j,17)+pbcqg(j,ibin)
+ end do
+ end do
+ if(pjcalc)then
+ do ibin=1,nobs_bins
+ pj(17,ibin)=pj(17,ibin)+pbcqg(1,ibin)+pbcqg(ipenloc,ibin)
+ end do
+ end if
end if
- end if ! ljclimqc
+ end if
+!$omp end parallel sections
+! end if ! ljclimqc
end if
+
! penalties for Jo
pbcjoi=zero_quad
call stpjo(dval,dbias,sval,sbias,sges,pbcjoi,nstep)
pbcjo=zero_quad
- do ibin=1,size(pbcjoi,3) ! == obs_bins
- do j=1,size(pbcjoi,2)
- do i=1,size(pbcjoi,1)
+ do ibin=1,nobs_bins ! == obs_bins
+ do j=1,nobs_type
+ do i=1,nstep
pbcjo(i,j)=pbcjo(i,j)+pbcjoi(i,j,ibin)
end do
end do
enddo
+ do j=1,nobs_type
+ do i=1,nstep
+ pbc(i,n0+j)=pbcjo(i,j)
+ end do
+ end do
if(pjcalc)then
- do ibin=1,size(pbcjoi,3)
- do j=1,size(pbcjoi,2)
+ do ibin=1,nobs_bins
+ do j=1,nobs_type
pj(n0+j,ibin)=pj(n0+j,ibin)+pbcjoi(ipenloc,j,ibin)+pbcjoi(1,j,ibin)
end do
enddo
endif
- do j=1,size(pbcjo,2)
- do i=1,size(pbcjo,1)
- pbc(i,n0+j)=pbcjo(i,j)
- end do
- end do
! Gather J contributions
call mpl_allreduce(4,ipen,pbc)
@@ -718,114 +729,99 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
! estimate of stepsize
+ istp_use=ii
stp(ii)=stp(ii-1)
- if(cx > 1.e-20_r_kind) then
- stp(ii)=stp(ii)+bx/cx ! step size estimate
- else
-! Check for cx <= 0. (probable error or large nonlinearity)
- if(mype == 0) then
- write(iout_iter,*) ' entering cx <=0 stepsize option',cx,stp(ii)
- write(iout_iter,105) (bsum(i),i=1,ipen)
- write(iout_iter,110) (csum(i),i=1,ipen)
- end if
- stp(ii)=outstp(ipenloc)
- outpensave=outpen(ipenloc)
- do i=1,nsteptot
- if(outpen(i) < outpensave)then
- stp(ii)=outstp(i)
- outpensave=outpen(i)
- end if
- end do
- if(outpensave < outpen(ipenloc))then
- if(mype == 0)write(iout_iter,*) ' early termination due to cx <=0 ',cx,stp(ii)
- cxterm=.true.
- else
-! Try different (better?) stepsize
- stp(ii)=max(outstp(1),1.0e-20_r_kind)
- do i=2,nsteptot
- if(outstp(i) < stp(ii) .and. outstp(i) > 1.0e-20_r_kind)stp(ii)=outstp(i)
- end do
- stp(ii)=one_tenth_quad*stp(ii)
- change_dels=.false.
- end if
- end if
-
+ if(cx > 1.e-20_r_quad) stp(ii)=stp(ii)+bx/cx ! step size estimate
! estimate various terms in penalty on first iteration
if(ii == 1)then
- do i=1,ipen
- pen_save(i)=pbc(1,i)
- bsum_save(i)=bsum(i)
- csum_save(i)=csum(i)
- end do
- pjcost(1) = pen_save(1)+pbc(ipenloc,1) ! Jb
+ pjcost(1) = pbc(1,1)+pbc(ipenloc,1) ! Jb
pjcost(2) = zero_quad
do i=1,nobs_type
- pjcost(2) = pjcost(2)+pen_save(n0+i)+pbc(ipenloc,n0+i) ! Jo
+ pjcost(2) = pjcost(2)+pbc(1,n0+i)+pbc(ipenloc,n0+i) ! Jo
end do
- pjcost(3) = pen_save(2) + pen_save(3)+pbc(ipenloc,3) ! Jc
+ pjcost(3) = pbc(1,2) + pbc(1,3)+pbc(ipenloc,3) ! Jc
pjcost(4) = zero_quad
do i=4,n0
- pjcost(4) = pjcost(4) + pen_save(i)+pbc(ipenloc,i) ! Jl
+ pjcost(4) = pjcost(4) + pbc(1,i)+pbc(ipenloc,i) ! Jl
end do
penalty=pjcost(1)+pjcost(2)+pjcost(3)+pjcost(4) ! J = Jb + Jo + Jc +Jl
! Write out detailed results to iout_iter
- if(mype == 0) then
- write(iout_iter,100) (pen_save(i)+pbc(ipenloc,i),i=1,ipen)
- if(print_verbose)then
- write(iout_iter,105) (bsum(i),i=1,ipen)
- write(iout_iter,110) (csum(i),i=1,ipen)
- end if
- end if
- endif
-
-! estimate of change in penalty
- delpen = stp(ii)*(bx - 0.5_r_quad*stp(ii)*cx )
-
-! If change in penalty is very small end stepsize calculation
- if(abs(delpen/penalty) < 1.e-17_r_kind) then
- if(mype == 0)then
- write(iout_iter,*) ' minimization has converged '
- write(iout_iter,140) ii,delpen,bx,cx,stp(ii)
+ if(mype == minmype) then
write(iout_iter,100) (pbc(1,i)+pbc(ipenloc,i),i=1,ipen)
if(print_verbose)then
write(iout_iter,105) (bsum(i),i=1,ipen)
write(iout_iter,110) (csum(i),i=1,ipen)
end if
end if
- end_iter = .true.
-! Finalize timer
- call timer_fnl('stpcalc')
- istp_use=ii
- exit stepsize
- end if
+ endif
-! Check for negative stepsize (probable error or large nonlinearity)
- if(stp(ii) <= zero_quad) then
- if(mype == 0) then
- write(iout_iter,*) ' entering negative stepsize option',stp(ii)
+ if(cx <= 1.e-20_r_quad .or. stp(ii) <= zero_quad)then
+! Check for cx <= 0 or. stp(ii) < zero. (probable error or large nonlinearity)
+ if(mype == minmype) then
+ write(iout_iter,*) ' entering cx <=0 or stp <= 0 stepsize option',cx,stp(ii)
write(iout_iter,105) (bsum(i),i=1,ipen)
write(iout_iter,110) (csum(i),i=1,ipen)
end if
stp(ii)=outstp(ipenloc)
outpensave=outpen(ipenloc)
- do i=1,nsteptot
+ do i=1,ii
if(outpen(i) < outpensave)then
- stp(ii)=outstp(i)
outpensave=outpen(i)
+ istp_use=i
end if
end do
+ if(istp_use /= ii .and. stp(istp_use) > zero_quad)then
+ if(mype == minmype)then
+ write(iout_iter,*) ' early termination due to cx or stp <=0 ',cx,stp(ii)
+ write(iout_iter,*) ' better stepsize found',cx,stp(ii)
+ end if
+ final_ii=ii
+ exit stepsize
+ else if(ii == istp_iter)then
+ if(mype == minmype)then
+ write(iout_iter,*) ' early termination due to no decrease in penalty ',cx,stp(ii)
+ end if
+ stp(istp_use)=zero
+ end_iter = .true.
+ final_ii=ii
+ exit stepsize
+ else
! Try different (better?) stepsize
- if(stp(ii) <= zero_quad .and. ii /= istp_iter)then
- stp(ii)=max(outstp(1),1.0e-20_r_kind)
- do i=2,nsteptot
- if(outstp(i) < stp(ii) .and. outstp(i) > 1.0e-20_r_kind)stp(ii)=outstp(i)
- end do
- stp(ii)=one_tenth_quad*stp(ii)
- change_dels=.false.
+ stp(ii)=one_tenth_quad*max(outstp(1),1.0e-20_r_kind)
end if
+ else
+
+! estimate of change in penalty
+ delpen = stp(ii)*(bx - 0.5_r_quad*stp(ii)*cx )
+
+! If change in penalty is very small end stepsize calculation
+ if(abs(delpen/penalty) < 1.e-17_r_kind) then
+ if(mype == minmype)then
+ write(iout_iter,*) ' minimization has converged '
+ write(iout_iter,140) ii,delpen,bx,cx,stp(ii)
+ write(iout_iter,100) (pbc(1,i)+pbc(ipenloc,i),i=1,ipen)
+ if(print_verbose)then
+ write(iout_iter,105) (bsum(i),i=1,ipen)
+ write(iout_iter,110) (csum(i),i=1,ipen)
+ end if
+ end if
+ end_iter = .true.
+! Finalize timer
+ call timer_fnl('stpcalc')
+ final_ii=ii
+ exit stepsize
+ end if
+! Check for convergence in stepsize estimation
+ stprat(ii)=zero
+ if(stp(ii) > zero_quad)stprat(ii)=abs((stp(ii)-stp(ii-1))/stp(ii))
+ if(stprat(ii) < 1.e-4_r_kind) then
+ final_ii=ii
+ exit stepsize
+ end if
+ dels = one_tenth_quad*dels
end if
100 format(' J=',3e25.18/,(3x,3e25.18))
@@ -839,75 +835,50 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
141 format('***WARNING*** reduced penalty not found in search direction',/, &
' - probable error',(5e25.18))
-! Check for convergence in stepsize estimation
- istp_use=ii
- if(cxterm) exit stepsize
- stprat(ii)=zero
- if(stp(ii) > zero)then
- stprat(ii)=abs((stp(ii)-stp(ii-1))/stp(ii))
- end if
- if(stprat(ii) < 1.e-4_r_kind) exit stepsize
- if(change_dels)dels = one_tenth_quad*dels
! If stepsize estimate has not converged use best stepsize estimate or zero
if( ii == istp_iter)then
stp(ii)=outstp(ipenloc)
outpensave=outpen(ipenloc)
- ifound=.false.
! Find best stepsize to this point
do i=1,nsteptot
if(outpen(i) < outpensave)then
stp(ii)=outstp(i)
outpensave=outpen(i)
- ifound=.true.
+ istp_use=ii
end if
end do
- if(ifound)exit stepsize
+ if(istp_use /= nsteptot) then
+ final_ii=ii
+ exit stepsize
+ end if
! If no best stepsize set to zero and end minimization
- if(mype == 0)then
+ if(mype == minmype)then
write(iout_iter,141)(outpen(i),i=1,nsteptot)
end if
end_iter = .true.
stp(ii)=zero_quad
istp_use=ii
+ final_ii=ii
exit stepsize
end if
+ final_ii=ii
end do stepsize
+
if(kprt >= 2 .and. iter == 0)then
call mpl_allreduce(ipen,nobs_bins,pj)
- if(mype == 0)call prnt_j(pj,n0,ipen,kprt)
+ if(mype == minmype)call prnt_j(pj,n0,ipen,kprt)
end if
stpinout=stp(istp_use)
-! Estimate terms in penalty
- if(mype == 0 .and. print_verbose)then
- do i=1,ipen
- pen_est(i)=pen_save(i)-(stpinout-stp(0))*(2.0_r_quad*bsum_save(i)- &
- (stpinout-stp(0))*csum_save(i))
- end do
- write(iout_iter,101) (pbc(1,i)-pen_est(i),i=1,ipen)
- end if
- pjcostnew(1) = pbc(1,1) ! Jb
- pjcostnew(3) = pbc(1,2)+pbc(1,3) ! Jc
- pjcostnew(4)=zero
- do i=4,n0
- pjcostnew(4) = pjcostnew(4) + pbc(1,i) ! Jl
- end do
- pjcostnew(2) = zero
- do i=1,nobs_type
- pjcostnew(2) = pjcostnew(2)+pbc(1,n0+i) ! Jo
- end do
- penaltynew=pjcostnew(1)+pjcostnew(2)+pjcostnew(3)+pjcostnew(4)
- if(mype == 0 .and. print_verbose)then
- write(iout_iter,200) (stp(i),i=0,istp_use)
- write(iout_iter,199) (stprat(ii),ii=1,istp_use)
- write(iout_iter,201) (outstp(i),i=1,nsteptot)
- write(iout_iter,202) (outpen(i)-outpen(4),i=1,nsteptot)
- end if
! Check for final stepsize negative (probable error)
if(stpinout <= zero)then
- if(mype == 0)then
- write(iout_iter,130) ii,bx,cx,stp(ii)
+ if(mype == minmype)then
+ do i=1,ipen
+ pen_est(i)=pbc(1,i)-(stpinout-stp(0))*(2.0_r_quad*bsum(i)- &
+ (stpinout-stp(0))*csum(i))
+ end do
+ write(iout_iter,130) final_ii,bx,cx,stp(final_ii)
write(iout_iter,105) (bsum(i),i=1,ipen)
write(iout_iter,110) (csum(i),i=1,ipen)
write(iout_iter,101) (pbc(1,i)-pen_est(i),i=1,ipen)
@@ -920,26 +891,49 @@ subroutine stpcalc(stpinout,sval,sbias,dirx,dval,dbias, &
202 format(' penalties = ',(10(e13.6,1x)))
! If convergence or failure of stepsize calculation return
- if (end_iter) then
- call timer_fnl('stpcalc')
- return
- endif
+! Estimate terms in penalty
+ if(mype == minmype)then
+ pjcostnew(1) = pbc(1,1) ! Jb
+ pjcostnew(3) = pbc(1,2)+pbc(1,3) ! Jc
+ pjcostnew(4)=zero
+ do i=4,n0
+ pjcostnew(4) = pjcostnew(4) + pbc(1,i) ! Jl
+ end do
+ pjcostnew(2) = zero
+ do i=1,nobs_type
+ pjcostnew(2) = pjcostnew(2)+pbc(1,n0+i) ! Jo
+ end do
+ penaltynew=pjcostnew(1)+pjcostnew(2)+pjcostnew(3)+pjcostnew(4)
+
+ if(print_verbose)then
+ write(iout_iter,200) (stp(i),i=0,istp_use)
+ write(iout_iter,199) (stprat(i),i=1,istp_use)
+ write(iout_iter,201) (outstp(i),i=1,nsteptot)
+ write(iout_iter,202) (outpen(i)-outpen(4),i=1,nsteptot)
+ end if
+ end if
+
+ if (.not. end_iter) then
! Update solution
- do i=1,nrclen
- sbias%values(i)=sbias%values(i)+stpinout*dbias%values(i)
- end do
!$omp parallel do schedule(dynamic,1) private(i,ii)
- do ii=1,nobs_bins
- do i=1,sval(ii)%ndim
- sval(ii)%values(i)=sval(ii)%values(i)+stpinout*dval(ii)%values(i)
+ do ii=1,nobs_bins+2
+ if(ii <= nobs_bins)then
+ do i=1,sval(ii)%ndim
+ sval(ii)%values(i)=sval(ii)%values(i)+stpinout*dval(ii)%values(i)
+ end do
+ else if(ii == nobs_bins+1)then
+ do i=1,nrclen
+ sbias%values(i)=sbias%values(i)+stpinout*dbias%values(i)
+ end do
+ else
+ do i=1,nclen
+ xhatsave%values(i)=xhatsave%values(i)+stpinout*dirx%values(i)
+ yhatsave%values(i)=yhatsave%values(i)+stpinout*diry%values(i)
+ end do
+ end if
end do
- end do
-!DIR$ IVDEP
- do i=1,nclen
- xhatsave%values(i)=xhatsave%values(i)+stpinout*dirx%values(i)
- yhatsave%values(i)=yhatsave%values(i)+stpinout*diry%values(i)
- end do
+ endif
! Finalize timer
@@ -975,6 +969,7 @@ subroutine prnt_j(pj,n0,ipen,kprt)
use mpimod, only: mype
use gsi_obOperTypeManager, only: nobs_type => obOper_count
use gsi_obOperTypeManager, only: obOper_typeInfo
+ use gridmod, only: minmype
real(r_quad),dimension(ipen,nobs_bins),intent(in ) :: pj
integer(i_kind) ,intent(in ) :: n0,ipen,kprt
@@ -986,7 +981,7 @@ subroutine prnt_j(pj,n0,ipen,kprt)
integer(i_kind) :: ii,jj
character(len=20) :: ctype(ipen)
- if(kprt <=0 .or. mype /=0)return
+ if(kprt <=0 .or. mype /=minmype)return
ctype(:)=".unknown."
ctype(1)='background '
ctype(2)=' '
diff --git a/src/gsi/stpfed.f90 b/src/gsi/stpfed.f90
new file mode 100644
index 0000000000..6511a27968
--- /dev/null
+++ b/src/gsi/stpfed.f90
@@ -0,0 +1,169 @@
+module stpfedmod
+
+!$$$ module documentation block
+! . . . .
+! module: stpfedmod module for stpfed and its tangent linear stpfed_tl
+! prgmmr:
+!
+! abstract: module for stpfed and its tangent linear stpfed_tl
+!
+! program history log:
+! 2023-08-23 H. Wang - Modified based on sftdbzmod
+! - add adjoint of fed operator
+!
+! subroutines included:
+! sub stpfed
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+implicit none
+
+PRIVATE
+PUBLIC stpfed
+
+contains
+
+subroutine stpfed(fedhead,rval,sval,out,sges,nstep)
+!$$$ subprogram documentation block
+! . . . .
+! subprogram: stpfed calculate penalty and contribution to
+! stepsize with nonlinear qc added.
+! prgmmr: derber org: np23 date: 1991-02-26
+!
+!
+! program history log:
+! 2019-08-23 H.Wang - added for FED DA
+! input argument list:
+! fedhead
+! sges - step size estimates (nstep)
+! nstep - number of step sizes (== 0 means use outer iteration value)
+!
+! output argument list - output for step size calculation
+! out(1:nstep) - penalty from fed sges(1:nstep)
+!
+! attributes:
+! language: f90
+! machine: ibm RS/6000 SP
+!
+!$$$
+ use kinds, only: r_kind,i_kind,r_quad
+ use qcmod, only: nlnqc_iter,varqc_iter
+ use constants, only: half,one,two,tiny_r_kind,cg_term,zero_quad,r3600
+ use gsi_bundlemod, only: gsi_bundle
+ use gsi_bundlemod, only: gsi_bundlegetpointer
+ use wrf_vars_mod, only : fed_exist
+ use m_obsNode, only: obsNode
+ use m_fedNode , only: fedNode
+ use m_fedNode , only: fedNode_typecast
+ use m_fedNode , only: fedNode_nextcast
+! use directDA_radaruse_mod, only: l_use_fed_directDA
+
+ implicit none
+
+! Declare passed variables
+ class(obsNode), pointer ,intent(in ) :: fedhead
+ integer(i_kind) ,intent(in ) :: nstep
+ real(r_quad),dimension(max(1,nstep)),intent(inout) :: out
+ type(gsi_bundle) ,intent(in ) :: rval,sval
+ real(r_kind),dimension(max(1,nstep)),intent(in ) :: sges
+
+! Declare local variables
+ integer(i_kind) ier,istatus
+ integer(i_kind) j1,j2,j3,j4,j5,j6,j7,j8,kk
+ real(r_kind) w1,w2,w3,w4,w5,w6,w7,w8
+ real(r_kind) valfed
+ real(r_kind) fedcur
+ real(r_kind) cg_fed,fed,wgross,wnotgross
+ real(r_kind),dimension(max(1,nstep))::pen
+ real(r_kind) pg_fed
+ real(r_kind),pointer,dimension(:) :: sfed
+ real(r_kind),pointer,dimension(:) :: rfed
+ type(fedNode), pointer :: fedptr
+
+ out=zero_quad
+
+! If no fed data return
+ if(.not. associated(fedhead))return
+
+! Retrieve pointers
+! Simply return if any pointer not found
+ ier=0
+ if(fed_exist)then
+ call gsi_bundlegetpointer(sval,'fed',sfed,istatus);ier=istatus+ier
+ call gsi_bundlegetpointer(rval,'fed',rfed,istatus);ier=istatus+ier
+ else
+ return
+ end if
+
+ if(ier/=0)return
+
+ fedptr => fedNode_typecast(fedhead)
+ do while (associated(fedptr))
+ if(fedptr%luse)then
+ if(nstep > 0)then
+ j1=fedptr%ij(1)
+ j2=fedptr%ij(2)
+ j3=fedptr%ij(3)
+ j4=fedptr%ij(4)
+ j5=fedptr%ij(5)
+ j6=fedptr%ij(6)
+ j7=fedptr%ij(7)
+ j8=fedptr%ij(8)
+ w1=fedptr%wij(1)
+ w2=fedptr%wij(2)
+ w3=fedptr%wij(3)
+ w4=fedptr%wij(4)
+ w5=fedptr%wij(5)
+ w6=fedptr%wij(6)
+ w7=fedptr%wij(7)
+ w8=fedptr%wij(8)
+
+ if( fed_exist )then
+ valfed= w1* rfed(j1)+w2*rfed(j2)+w3*rfed(j3)+w4*rfed(j4)+ &
+ w5* rfed(j5)+w6*rfed(j6)+w7*rfed(j7)+w8*rfed(j8)
+
+ fedcur= w1* sfed(j1)+w2* sfed(j2)+w3* sfed(j3)+w4*sfed(j4)+ &
+ w5* sfed(j5)+w6* sfed(j6)+w7* sfed(j7)+w8* sfed(j8)- &
+ fedptr%res
+ end if
+
+
+ do kk=1,nstep
+ fed=fedcur+sges(kk)*valfed
+ pen(kk)=fed*fed*fedptr%err2
+ end do
+ else
+ pen(1)=fedptr%res*fedptr%res*fedptr%err2
+ end if
+
+! Modify penalty term if nonlinear QC
+ if (nlnqc_iter .and. fedptr%pg > tiny_r_kind .and. &
+ fedptr%b > tiny_r_kind) then
+
+ pg_fed=fedptr%pg*varqc_iter
+ cg_fed=cg_term/fedptr%b
+ wnotgross= one-pg_fed
+ wgross = pg_fed*cg_fed/wnotgross
+ do kk=1,max(1,nstep)
+ pen(kk)= -two*log((exp(-half*pen(kk)) + wgross)/(one+wgross))
+ end do
+ end if
+
+ out(1) = out(1)+pen(1)*fedptr%raterr2
+ kk=1
+ do kk=2,nstep
+ out(kk) = out(kk)+(pen(kk)-pen(1))*fedptr%raterr2
+ end do
+ end if
+
+ fedptr => fedNode_nextcast(fedptr)
+
+ end do
+ return
+end subroutine stpfed
+
+end module stpfedmod
diff --git a/src/gsi/stpgps.f90 b/src/gsi/stpgps.f90
index f55e9f4292..d357df1c05 100644
--- a/src/gsi/stpgps.f90
+++ b/src/gsi/stpgps.f90
@@ -107,12 +107,13 @@ subroutine stpgps(gpshead,rval,sval,out,sges,nstep)
real(r_kind),dimension(max(1,nstep)),intent(in ) :: sges
! Declare local variables
- integer(i_kind) j,kk,ier,istatus
- integer(i_kind),dimension(nsig):: i1,i2,i3,i4
+ integer(i_kind):: j,kk,ier,istatus
+ integer(i_kind):: i1,i2,i3,i4
real(r_kind) :: val,val2
real(r_kind) :: w1,w2,w3,w4
real(r_kind) :: q_TL,p_TL,t_TL
real(r_kind) :: rq_TL,rp_TL,rt_TL
+ real(r_kind),dimension(nsig) :: valk2,valk
real(r_kind),pointer,dimension(:) :: st,sq
real(r_kind),pointer,dimension(:) :: rt,rq
real(r_kind),pointer,dimension(:) :: sp
@@ -149,34 +150,33 @@ subroutine stpgps(gpshead,rval,sval,out,sges,nstep)
val2=-gpsptr%res
if(nstep > 0)then
- do j=1,nsig
- i1(j)= gpsptr%ij(1,j)
- i2(j)= gpsptr%ij(2,j)
- i3(j)= gpsptr%ij(3,j)
- i4(j)= gpsptr%ij(4,j)
- enddo
w1=gpsptr%wij(1)
w2=gpsptr%wij(2)
w3=gpsptr%wij(3)
w4=gpsptr%wij(4)
- val=zero
-
-
+!$omp parallel do schedule(dynamic,1) private(j,t_TL,rt_TL,q_TL,rq_TL,p_TL,rp_TL,i1,i2,i3,i4)
do j=1,nsig
- t_TL =w1* st(i1(j))+w2* st(i2(j))+w3* st(i3(j))+w4* st(i4(j))
- rt_TL=w1* rt(i1(j))+w2* rt(i2(j))+w3* rt(i3(j))+w4* rt(i4(j))
- q_TL =w1* sq(i1(j))+w2* sq(i2(j))+w3* sq(i3(j))+w4* sq(i4(j))
- rq_TL=w1* rq(i1(j))+w2* rq(i2(j))+w3* rq(i3(j))+w4* rq(i4(j))
- p_TL =w1* sp(i1(j))+w2* sp(i2(j))+w3* sp(i3(j))+w4* sp(i4(j))
- rp_TL=w1* rp(i1(j))+w2* rp(i2(j))+w3* rp(i3(j))+w4* rp(i4(j))
- val2 = val2 + t_tl*gpsptr%jac_t(j)+ q_tl*gpsptr%jac_q(j)+p_tl*gpsptr%jac_p(j)
- val = val + rt_tl*gpsptr%jac_t(j)+rq_tl*gpsptr%jac_q(j)+rp_tl*gpsptr%jac_p(j)
-
+ i1= gpsptr%ij(1,j)
+ i2= gpsptr%ij(2,j)
+ i3= gpsptr%ij(3,j)
+ i4= gpsptr%ij(4,j)
+ t_TL =w1* st(i1)+w2* st(i2)+w3* st(i3)+w4* st(i4)
+ rt_TL=w1* rt(i1)+w2* rt(i2)+w3* rt(i3)+w4* rt(i4)
+ q_TL =w1* sq(i1)+w2* sq(i2)+w3* sq(i3)+w4* sq(i4)
+ rq_TL=w1* rq(i1)+w2* rq(i2)+w3* rq(i3)+w4* rq(i4)
+ p_TL =w1* sp(i1)+w2* sp(i2)+w3* sp(i3)+w4* sp(i4)
+ rp_TL=w1* rp(i1)+w2* rp(i2)+w3* rp(i3)+w4* rp(i4)
+ valk2(j) = t_tl*gpsptr%jac_t(j)+ q_tl*gpsptr%jac_q(j)+ p_tl*gpsptr%jac_p(j)
+ valk(j) = rt_tl*gpsptr%jac_t(j)+rq_tl*gpsptr%jac_q(j)+rp_tl*gpsptr%jac_p(j)
enddo
-
+ val=zero
+ do j=1,nsig
+ val2 = val2 + valk2(j)
+ val = val + valk(j)
+ enddo
! penalty and gradient
do kk=1,nstep
diff --git a/src/gsi/stpjcmod.f90 b/src/gsi/stpjcmod.f90
index 2c811912a0..1cdabe60eb 100644
--- a/src/gsi/stpjcmod.f90
+++ b/src/gsi/stpjcmod.f90
@@ -871,7 +871,7 @@ subroutine stpjcpdry(rval,sval,pen,b,c,nbins)
it=ntguessig
dmass=zero_quad
- rcon=one_quad/(two_quad*float(nlon))
+ rcon=one_quad/(two_quad*real(nlon,r_quad))
mm1=mype+1
return_now = .false.
do n=1,nbins
diff --git a/src/gsi/stpjo.f90 b/src/gsi/stpjo.f90
index b0ff730823..0f80d9b4a2 100644
--- a/src/gsi/stpjo.f90
+++ b/src/gsi/stpjo.f90
@@ -267,8 +267,6 @@ subroutine stpjo(dval,dbias,xval,xbias,sges,pbcjo,nstep)
use m_obsdiags, only: obOper_destroy
use gsi_obOperTypeManager, only: obOper_typeInfo
- use intradmod, only: setrad
-
use mpeu_util, only: perr,die
use mpeu_util, only: tell
use mpeu_mpif, only: MPI_comm_world
@@ -290,7 +288,6 @@ subroutine stpjo(dval,dbias,xval,xbias,sges,pbcjo,nstep)
class(obOper),pointer:: it_obOper
!************************************************************************************
- call setrad(xval(1))
!$omp parallel do schedule(dynamic,1) private(ll,mm,ib,it_obOper)
do mm=1,stpcnt
diff --git a/src/gsi/stprad.f90 b/src/gsi/stprad.f90
index 0def855d61..e81688f7e3 100644
--- a/src/gsi/stprad.f90
+++ b/src/gsi/stprad.f90
@@ -110,7 +110,7 @@ subroutine stprad(radhead,dval,xval,rpred,spred,out,sges,nstep)
use gsi_metguess_mod, only: gsi_metguess_get
use mpeu_util, only: getindex
use intradmod, only: luseu,lusev,luset,luseq,lusecw,luseoz,luseqg,luseqh,luseqi,luseql, &
- luseqr,luseqs
+ luseqr,luseqs,lusesst
use intradmod, only: itsen,iqv,ioz,icw,ius,ivs,isst,iqg,iqh,iqi,iql,iqr,iqs,lgoback
use m_obsNode, only: obsNode
use m_radNode, only: radNode
@@ -128,14 +128,15 @@ subroutine stprad(radhead,dval,xval,rpred,spred,out,sges,nstep)
type(gsi_bundle),intent(in) :: xval
! Declare local variables
- integer(i_kind) istatus
- integer(i_kind) nn,n,ic,k,nx,j1,j2,j3,j4,kk, mm, ic1,ncr
+ integer(i_kind) istatus,icx
+ integer(i_kind) nn,n,ic,k,nx,j1,j2,j3,j4,kk,mm,ncr
real(r_kind) val2,val,w1,w2,w3,w4
real(r_kind),dimension(nsigradjac):: tdir,rdir
real(r_kind) cg_rad,wgross,wnotgross
integer(i_kind),dimension(nsig) :: j1n,j2n,j3n,j4n
- real(r_kind),dimension(max(1,nstep)) :: term,rad
+ real(r_kind),dimension(max(1,nstep)) :: rad
type(radNode), pointer :: radptr
+ real(r_kind),allocatable,dimension(:,:) :: term
real(r_kind),allocatable,dimension(:) :: biasvects
real(r_kind),allocatable,dimension(:) :: biasvectr
real(r_kind),pointer,dimension(:) :: rt,rq,rcw,roz,ru,rv,rqg,rqh,rqi,rql,rqr,rqs
@@ -150,34 +151,59 @@ subroutine stprad(radhead,dval,xval,rpred,spred,out,sges,nstep)
if(lgoback)return
-! Retrieve pointers
- call gsi_bundlegetpointer(xval,'u', su, istatus)
- call gsi_bundlegetpointer(xval,'v', sv, istatus)
- call gsi_bundlegetpointer(xval,'tsen' ,st, istatus)
- call gsi_bundlegetpointer(xval,'q', sq, istatus)
- call gsi_bundlegetpointer(xval,'cw' ,scw,istatus)
- call gsi_bundlegetpointer(xval,'oz' ,soz,istatus)
- call gsi_bundlegetpointer(xval,'sst',sst,istatus)
- call gsi_bundlegetpointer(xval,'qg' ,sqg,istatus)
- call gsi_bundlegetpointer(xval,'qh' ,sqh,istatus)
- call gsi_bundlegetpointer(xval,'qi' ,sqi,istatus)
- call gsi_bundlegetpointer(xval,'ql' ,sql,istatus)
- call gsi_bundlegetpointer(xval,'qr' ,sqr,istatus)
- call gsi_bundlegetpointer(xval,'qs' ,sqs,istatus)
-
- call gsi_bundlegetpointer(dval,'u', ru, istatus)
- call gsi_bundlegetpointer(dval,'v', rv, istatus)
- call gsi_bundlegetpointer(dval,'tsen' ,rt, istatus)
- call gsi_bundlegetpointer(dval,'q', rq, istatus)
- call gsi_bundlegetpointer(dval,'cw' ,rcw,istatus)
- call gsi_bundlegetpointer(dval,'oz' ,roz,istatus)
- call gsi_bundlegetpointer(dval,'sst',rst,istatus)
- call gsi_bundlegetpointer(dval,'qg' ,rqg,istatus)
- call gsi_bundlegetpointer(dval,'qh' ,rqh,istatus)
- call gsi_bundlegetpointer(dval,'qi' ,rqi,istatus)
- call gsi_bundlegetpointer(dval,'ql' ,rql,istatus)
- call gsi_bundlegetpointer(dval,'qr' ,rqr,istatus)
- call gsi_bundlegetpointer(dval,'qs' ,rqs,istatus)
+! Retrieve pointers for used variables
+ if(luseu)then
+ call gsi_bundlegetpointer(dval,'u', ru, istatus)
+ call gsi_bundlegetpointer(xval,'u', su, istatus)
+ end if
+ if(lusev)then
+ call gsi_bundlegetpointer(xval,'v', sv, istatus)
+ call gsi_bundlegetpointer(dval,'v', rv, istatus)
+ end if
+ if(luset)then
+ call gsi_bundlegetpointer(xval,'tsen' ,st, istatus)
+ call gsi_bundlegetpointer(dval,'tsen' ,rt, istatus)
+ end if
+ if(luseq)then
+ call gsi_bundlegetpointer(xval,'q', sq, istatus)
+ call gsi_bundlegetpointer(dval,'q', rq, istatus)
+ end if
+ if(lusecw)then
+ call gsi_bundlegetpointer(xval,'cw' ,scw,istatus)
+ call gsi_bundlegetpointer(dval,'cw' ,rcw,istatus)
+ end if
+ if(luseoz)then
+ call gsi_bundlegetpointer(xval,'oz' ,soz,istatus)
+ call gsi_bundlegetpointer(dval,'oz' ,roz,istatus)
+ end if
+ if(lusesst)then
+ call gsi_bundlegetpointer(xval,'sst',sst,istatus)
+ call gsi_bundlegetpointer(dval,'sst',rst,istatus)
+ end if
+ if(luseqg)then
+ call gsi_bundlegetpointer(xval,'qg' ,sqg,istatus)
+ call gsi_bundlegetpointer(dval,'qg' ,rqg,istatus)
+ end if
+ if(luseqh)then
+ call gsi_bundlegetpointer(xval,'qh' ,sqh,istatus)
+ call gsi_bundlegetpointer(dval,'qh' ,rqh,istatus)
+ end if
+ if(luseqi)then
+ call gsi_bundlegetpointer(xval,'qi' ,sqi,istatus)
+ call gsi_bundlegetpointer(dval,'qi' ,rqi,istatus)
+ end if
+ if(luseql)then
+ call gsi_bundlegetpointer(xval,'ql' ,sql,istatus)
+ call gsi_bundlegetpointer(dval,'ql' ,rql,istatus)
+ end if
+ if(luseqr)then
+ call gsi_bundlegetpointer(xval,'qr' ,sqr,istatus)
+ call gsi_bundlegetpointer(dval,'qr' ,rqr,istatus)
+ end if
+ if(luseqs)then
+ call gsi_bundlegetpointer(xval,'qs' ,sqs,istatus)
+ call gsi_bundlegetpointer(dval,'qs' ,rqs,istatus)
+ end if
tdir=zero
@@ -187,118 +213,117 @@ subroutine stprad(radhead,dval,xval,rpred,spred,out,sges,nstep)
do while(associated(radptr))
if(radptr%luse)then
if(nstep > 0)then
- j1=radptr%ij(1)
- j2=radptr%ij(2)
- j3=radptr%ij(3)
- j4=radptr%ij(4)
w1=radptr%wij(1)
w2=radptr%wij(2)
w3=radptr%wij(3)
w4=radptr%wij(4)
- if(luseu)then
- tdir(ius+1)=w1* su(j1) + w2* su(j2) + w3* su(j3) + w4* su(j4)
- rdir(ius+1)=w1* ru(j1) + w2* ru(j2) + w3* ru(j3) + w4* ru(j4)
- endif
- if(lusev)then
- tdir(ivs+1)=w1* sv(j1) + w2* sv(j2) + w3* sv(j3) + w4* sv(j4)
- rdir(ivs+1)=w1* rv(j1) + w2* rv(j2) + w3* rv(j3) + w4* rv(j4)
- endif
- if (isst>=0) then
- tdir(isst+1)=w1*sst(j1) + w2*sst(j2) + w3*sst(j3) + w4*sst(j4)
- rdir(isst+1)=w1*rst(j1) + w2*rst(j2) + w3*rst(j3) + w4*rst(j4)
- end if
- j1n(1) = j1
- j2n(1) = j2
- j3n(1) = j3
- j4n(1) = j4
+ j1n(1) = radptr%ij(1)
+ j2n(1) = radptr%ij(2)
+ j3n(1) = radptr%ij(3)
+ j4n(1) = radptr%ij(4)
do n=2,nsig
j1n(n) = j1n(n-1)+latlon11
j2n(n) = j2n(n-1)+latlon11
j3n(n) = j3n(n-1)+latlon11
j4n(n) = j4n(n-1)+latlon11
enddo
- do n=1,nsig
- j1 = j1n(n)
- j2 = j2n(n)
- j3 = j3n(n)
- j4 = j4n(n)
-
-! Input state vector
-! Input search direction vector
- if(luset)then
- tdir(itsen+n)=w1* st(j1) +w2* st(j2) + w3* st(j3) +w4* st(j4)
- rdir(itsen+n)=w1* rt(j1) +w2* rt(j2) + w3* rt(j3) +w4* rt(j4)
- endif
- if(luseq)then
- tdir(iqv+n)=w1* sq(j1) +w2* sq(j2) + w3* sq(j3) +w4* sq(j4)
- rdir(iqv+n)=w1* rq(j1) +w2* rq(j2) + w3* rq(j3) +w4* rq(j4)
- endif
- if (luseoz) then
- tdir(ioz+n)=w1*soz(j1)+w2*soz(j2)+ w3*soz(j3)+w4*soz(j4)
- rdir(ioz+n)=w1*roz(j1)+w2*roz(j2)+ w3*roz(j3)+w4*roz(j4)
- end if
- if (lusecw) then
- tdir(icw+n)=w1*scw(j1)+w2*scw(j2)+ w3*scw(j3)+w4*scw(j4)
- rdir(icw+n)=w1*rcw(j1)+w2*rcw(j2)+ w3*rcw(j3)+w4*rcw(j4)
- end if
- if (luseqg) then
- tdir(iqg+n)=w1*sqg(j1)+w2*sqg(j2)+ w3*sqg(j3)+w4*sqg(j4)
- rdir(iqg+n)=w1*rqg(j1)+w2*rqg(j2)+ w3*rqg(j3)+w4*rqg(j4)
- end if
- if (luseqh) then
- tdir(iqh+n)=w1*sqh(j1)+w2*sqh(j2)+ w3*sqh(j3)+w4*sqh(j4)
- rdir(iqh+n)=w1*rqh(j1)+w2*rqh(j2)+ w3*rqh(j3)+w4*rqh(j4)
- end if
- if (luseqi) then
- tdir(iqi+n)=w1*sqi(j1)+w2*sqi(j2)+ w3*sqi(j3)+w4*sqi(j4)
- rdir(iqi+n)=w1*rqi(j1)+w2*rqi(j2)+ w3*rqi(j3)+w4*rqi(j4)
- end if
- if (luseql) then
- tdir(iql+n)=w1*sql(j1)+w2*sql(j2)+ w3*sql(j3)+w4*sql(j4)
- rdir(iql+n)=w1*rql(j1)+w2*rql(j2)+ w3*rql(j3)+w4*rql(j4)
- end if
- if (luseqr) then
- tdir(iqr+n)=w1*sqr(j1)+w2*sqr(j2)+ w3*sqr(j3)+w4*sqr(j4)
- rdir(iqr+n)=w1*rqr(j1)+w2*rqr(j2)+ w3*rqr(j3)+w4*rqr(j4)
+ allocate(biasvects(radptr%nchan))
+ allocate(biasvectr(radptr%nchan))
+ allocate(term(max(1,nstep),radptr%nchan))
+
+!$omp parallel do schedule(dynamic,1) private(n,j1,j2,j3,j4,icx,vals_quad,valr_quad,nx)
+ do n=1,max(nsig,radptr%nchan)
+ if(n <= nsig)then
+ j1 = j1n(n)
+ j2 = j2n(n)
+ j3 = j3n(n)
+ j4 = j4n(n)
+ if(n == 1)then
+ if(luseu)then
+ tdir(ius+1)=w1* su(j1) + w2* su(j2) + w3* su(j3) + w4* su(j4)
+ rdir(ius+1)=w1* ru(j1) + w2* ru(j2) + w3* ru(j3) + w4* ru(j4)
+ endif
+ if(lusev)then
+ tdir(ivs+1)=w1* sv(j1) + w2* sv(j2) + w3* sv(j3) + w4* sv(j4)
+ rdir(ivs+1)=w1* rv(j1) + w2* rv(j2) + w3* rv(j3) + w4* rv(j4)
+ endif
+ if (lusesst) then
+ tdir(isst+1)=w1*sst(j1) + w2*sst(j2) + w3*sst(j3) + w4*sst(j4)
+ rdir(isst+1)=w1*rst(j1) + w2*rst(j2) + w3*rst(j3) + w4*rst(j4)
+ end if
+ end if
+
+! Input state vector
+! Input search direction vector
+ if(luset)then
+ tdir(itsen+n)=w1* st(j1) +w2* st(j2) + w3* st(j3) +w4* st(j4)
+ rdir(itsen+n)=w1* rt(j1) +w2* rt(j2) + w3* rt(j3) +w4* rt(j4)
+ endif
+ if(luseq)then
+ tdir(iqv+n)=w1* sq(j1) +w2* sq(j2) + w3* sq(j3) +w4* sq(j4)
+ rdir(iqv+n)=w1* rq(j1) +w2* rq(j2) + w3* rq(j3) +w4* rq(j4)
+ endif
+ if (luseoz) then
+ tdir(ioz+n)=w1*soz(j1)+w2*soz(j2)+ w3*soz(j3)+w4*soz(j4)
+ rdir(ioz+n)=w1*roz(j1)+w2*roz(j2)+ w3*roz(j3)+w4*roz(j4)
+ end if
+ if (lusecw) then
+ tdir(icw+n)=w1*scw(j1)+w2*scw(j2)+ w3*scw(j3)+w4*scw(j4)
+ rdir(icw+n)=w1*rcw(j1)+w2*rcw(j2)+ w3*rcw(j3)+w4*rcw(j4)
+ end if
+ if (luseqg) then
+ tdir(iqg+n)=w1*sqg(j1)+w2*sqg(j2)+ w3*sqg(j3)+w4*sqg(j4)
+ rdir(iqg+n)=w1*rqg(j1)+w2*rqg(j2)+ w3*rqg(j3)+w4*rqg(j4)
+ end if
+ if (luseqh) then
+ tdir(iqh+n)=w1*sqh(j1)+w2*sqh(j2)+ w3*sqh(j3)+w4*sqh(j4)
+ rdir(iqh+n)=w1*rqh(j1)+w2*rqh(j2)+ w3*rqh(j3)+w4*rqh(j4)
+ end if
+ if (luseqi) then
+ tdir(iqi+n)=w1*sqi(j1)+w2*sqi(j2)+ w3*sqi(j3)+w4*sqi(j4)
+ rdir(iqi+n)=w1*rqi(j1)+w2*rqi(j2)+ w3*rqi(j3)+w4*rqi(j4)
+ end if
+ if (luseql) then
+ tdir(iql+n)=w1*sql(j1)+w2*sql(j2)+ w3*sql(j3)+w4*sql(j4)
+ rdir(iql+n)=w1*rql(j1)+w2*rql(j2)+ w3*rql(j3)+w4*rql(j4)
+ end if
+ if (luseqr) then
+ tdir(iqr+n)=w1*sqr(j1)+w2*sqr(j2)+ w3*sqr(j3)+w4*sqr(j4)
+ rdir(iqr+n)=w1*rqr(j1)+w2*rqr(j2)+ w3*rqr(j3)+w4*rqr(j4)
+ end if
+ if (luseqs) then
+ tdir(iqs+n)=w1*sqs(j1)+w2*sqs(j2)+ w3*sqs(j3)+w4*sqs(j4)
+ rdir(iqs+n)=w1*rqs(j1)+w2*rqs(j2)+ w3*rqs(j3)+w4*rqs(j4)
+ end if
end if
- if (luseqs) then
- tdir(iqs+n)=w1*sqs(j1)+w2*sqs(j2)+ w3*sqs(j3)+w4*sqs(j4)
- rdir(iqs+n)=w1*rqs(j1)+w2*rqs(j2)+ w3*rqs(j3)+w4*rqs(j4)
+ if(n <= radptr%nchan)then
+ icx=radptr%icx(n)
+ vals_quad = zero_quad
+ valr_quad = zero_quad
+ do nx=1,npred
+ vals_quad = vals_quad + spred(nx,icx)*radptr%pred(nx,n)
+ valr_quad = valr_quad + rpred(nx,icx)*radptr%pred(nx,n)
+ end do
+ biasvects(n) = vals_quad
+ biasvectr(n) = valr_quad
end if
-
end do
- end if
- if(nstep > 0)then
- allocate(biasvects(radptr%nchan))
- allocate(biasvectr(radptr%nchan))
- do nn=1,radptr%nchan
- ic1=radptr%icx(nn)
- vals_quad = zero_quad
- valr_quad = zero_quad
- do nx=1,npred
- vals_quad = vals_quad + spred(nx,ic1)*radptr%pred(nx,nn)
- valr_quad = valr_quad + rpred(nx,ic1)*radptr%pred(nx,nn)
- end do
- biasvects(nn) = vals_quad
- biasvectr(nn) = valr_quad
- end do
endif
- ncr=0
+! !$omp parallel do schedule(dynamic,1) private(nn,ic,mm,ncr,k,kk,rad,val,val2,cg_rad,wnotgross,wgross)
do nn=1,radptr%nchan
- val2=-radptr%res(nn)
-
if(nstep > 0)then
val = zero
+ val2=-radptr%res(nn)
! contribution from bias corection
ic=radptr%icx(nn)
if(radptr%use_corr_obs) then
do mm=1,nn
- ncr=ncr+1
+ ncr=radptr%iccerr(nn)+mm
val2=val2+radptr%rsqrtinv(ncr)*biasvects(mm)
val =val +radptr%rsqrtinv(ncr)*biasvectr(mm)
end do
@@ -318,12 +343,12 @@ subroutine stprad(radhead,dval,xval,rpred,spred,out,sges,nstep)
rad(kk)=val2+sges(kk)*val
end do
else
- rad(kk)= val2
+ rad(1)= -radptr%res(nn)
end if
! calculate contribution to J
do kk=1,max(1,nstep)
- term(kk) = radptr%err2(nn)*rad(kk)*rad(kk)
+ term(kk,nn) = radptr%err2(nn)*rad(kk)*rad(kk)
end do
! Modify penalty term if nonlinear QC
@@ -333,18 +358,23 @@ subroutine stprad(radhead,dval,xval,rpred,spred,out,sges,nstep)
wnotgross= one-pg_rad(ic)*varqc_iter
wgross = varqc_iter*pg_rad(ic)*cg_rad/wnotgross
do kk=1,max(1,nstep)
- term(kk) = -two*log((exp(-half*term(kk) ) + wgross)/(one+wgross))
+ term(kk,nn) = -two*log((exp(-half*term(kk,nn) ) + wgross)/(one+wgross))
end do
endif
- out(1) = out(1) + term(1)*radptr%raterr2(nn)
+ end do
+
+ deallocate(biasvects, biasvectr)
+
+ do nn=1,radptr%nchan
+ out(1) = out(1) + term(1,nn)*radptr%raterr2(nn)
do kk=2,nstep
- out(kk) = out(kk) + (term(kk)-term(1))*radptr%raterr2(nn)
+ out(kk) = out(kk) + (term(kk,nn)-term(1,nn))*radptr%raterr2(nn)
end do
end do
- if(nstep > 0) deallocate(biasvects, biasvectr)
+ deallocate(term)
end if
diff --git a/src/gsi/stprw.f90 b/src/gsi/stprw.f90
index 710d9baa23..a61a53f54b 100644
--- a/src/gsi/stprw.f90
+++ b/src/gsi/stprw.f90
@@ -83,6 +83,7 @@ subroutine stprw(rwhead,rval,sval,out,sges,nstep)
!
!$$$
use kinds, only: r_kind,i_kind,r_quad
+ use obsmod, only: if_use_w_vr
use qcmod, only: nlnqc_iter,varqc_iter
use constants, only: half,one,two,tiny_r_kind,cg_term,zero_quad,r3600
use gsi_bundlemod, only: gsi_bundle
@@ -123,19 +124,13 @@ subroutine stprw(rwhead,rval,sval,out,sges,nstep)
ier=0
call gsi_bundlegetpointer(sval,'u',su,istatus);ier=istatus+ier
call gsi_bundlegetpointer(sval,'v',sv,istatus);ier=istatus+ier
- call gsi_bundlegetpointer(sval,'w',sw,istatus)
- if (istatus==0) then
- include_w=.true.
- else
- include_w=.false.
- end if
call gsi_bundlegetpointer(rval,'u',ru,istatus);ier=istatus+ier
call gsi_bundlegetpointer(rval,'v',rv,istatus);ier=istatus+ier
- call gsi_bundlegetpointer(rval,'w',rw,istatus)
- if (istatus==0) then
- include_w=.true.
- else
- include_w=.false.
+ include_w=.false.
+ call gsi_bundlegetpointer(sval,'w',sw,istatus)
+ if (if_use_w_vr.and.istatus==0) then
+ call gsi_bundlegetpointer(rval,'w',rw,istatus)
+ if(istatus == 0)include_w=.true.
end if
if(ier/=0)return
diff --git a/src/gsi/stpsst.f90 b/src/gsi/stpsst.f90
index 222b67862c..765676010b 100644
--- a/src/gsi/stpsst.f90
+++ b/src/gsi/stpsst.f90
@@ -101,13 +101,13 @@ subroutine stpsst(ssthead,rval,sval,out,sges,nstep)
real(r_kind) pg_sst
real(r_kind),pointer,dimension(:) :: ssst
real(r_kind),pointer,dimension(:) :: rsst
- real(r_kind) tdir,rdir
type(sstNode), pointer :: sstptr
out=zero_quad
! If no sst data return
if(.not. associated(ssthead))return
+ if(.not. nst_gsi > 2 ) return
! Retrieve pointers
! Simply return if any pointer not found
@@ -129,15 +129,12 @@ subroutine stpsst(ssthead,rval,sval,out,sges,nstep)
w3=sstptr%wij(3)
w4=sstptr%wij(4)
- if ( nst_gsi > 2 .and. (sstptr%tz_tr > zero .and. sstptr%tz_tr <= one) ) then
- tdir = w1*ssst(j1)+w2*ssst(j2)+w3*ssst(j3)+w4*ssst(j4)
- rdir = w1*rsst(j1)+w2*rsst(j2)+w3*rsst(j3)+w4*rsst(j4)
- val = sstptr%tz_tr*rdir
- val2 = sstptr%tz_tr*tdir - sstptr%res
- else
- val =w1*rsst(j1)+w2*rsst(j2)+w3*rsst(j3)+w4*rsst(j4)
- val2=w1*ssst(j1)+w2*ssst(j2)+w3*ssst(j3)+w4*ssst(j4)-sstptr%res
- endif
+ val =w1*rsst(j1)+w2*rsst(j2)+w3*rsst(j3)+w4*rsst(j4)
+ val2=w1*ssst(j1)+w2*ssst(j2)+w3*ssst(j3)+w4*ssst(j4)
+
+ val = sstptr%tz_tr*val
+ val2 = sstptr%tz_tr*val2
+ val2=val2-sstptr%res
do kk=1,nstep
sst=val2+sges(kk)*val
diff --git a/src/gsi/stpt.f90 b/src/gsi/stpt.f90
index 27f5385ac1..5911d87b9d 100644
--- a/src/gsi/stpt.f90
+++ b/src/gsi/stpt.f90
@@ -184,7 +184,6 @@ subroutine stpt(thead,dval,xval,out,sges,nstep,rpred,spred)
w6=tptr%wij(6)
w7=tptr%wij(7)
w8=tptr%wij(8)
-! Note time derivative stuff not consistent for virtual temperature
if(tptr%tv_ob)then
val= w1*rtv(j1)+w2*rtv(j2)+w3*rtv(j3)+w4*rtv(j4)+ &
@@ -208,9 +207,6 @@ subroutine stpt(thead,dval,xval,out,sges,nstep,rpred,spred)
end do
end if
- do kk=1,nstep
- tt(kk)=val2+sges(kk)*val
- end do
if(tptr%use_sfc_model) then
@@ -229,8 +225,9 @@ subroutine stpt(thead,dval,xval,out,sges,nstep,rpred,spred)
valv2=w1* sv(j1)+w2* sv(j2)+w3* sv(j3)+w4* sv(j4)
valp =w1* rp(j1)+w2* rp(j2)+w3* rp(j3)+w4* rp(j4)
valp2=w1* sp(j1)+w2* sp(j2)+w3* sp(j3)+w4* sp(j4)
+
do kk=1,nstep
- ts_prime=tt(kk)
+ ts_prime=val2+sges(kk)*val
tg_prime=valsst2+sges(kk)*valsst
qs_prime=valq2+sges(kk)*valq
us_prime=valu2+sges(kk)*valu
@@ -239,14 +236,18 @@ subroutine stpt(thead,dval,xval,out,sges,nstep,rpred,spred)
tt(kk)=psfc_prime*tptr%tlm_tsfc(1) + tg_prime*tptr%tlm_tsfc(2) + &
ts_prime *tptr%tlm_tsfc(3) + qs_prime*tptr%tlm_tsfc(4) + &
- us_prime *tptr%tlm_tsfc(5) + vs_prime*tptr%tlm_tsfc(6)
+ us_prime *tptr%tlm_tsfc(5) + vs_prime*tptr%tlm_tsfc(6) - &
+ tptr%res
+ end do
+
+ else
+
+ do kk=1,nstep
+ tt(kk)=val2+sges(kk)*val-tptr%res
end do
end if
- do kk=1,nstep
- tt(kk)=tt(kk)-tptr%res
- end do
else
tt(1)=tptr%res
end if
diff --git a/src/gsi/stub_wrf_binary_interface.f90 b/src/gsi/stub_wrf_binary_interface.f90
index 201482df13..58ef9e004e 100644
--- a/src/gsi/stub_wrf_binary_interface.f90
+++ b/src/gsi/stub_wrf_binary_interface.f90
@@ -29,18 +29,26 @@ end subroutine convert_binary_mass_dummy
subroutine convert_binary_nmm_dummy(this,update_pint,ctph0,stph0,tlm0)
use kinds, only: r_kind
+ use constants, only: zero
implicit none
class(get_wrf_binary_interface_class), intent(inout) :: this
logical ,intent(inout) :: update_pint
real(r_kind),intent( out) :: ctph0,stph0,tlm0
+ ctph0 = zero
+ stph0 = zero
+ tlm0 = zero
end subroutine convert_binary_nmm_dummy
subroutine convert_nems_nmmb_dummy(this,update_pint,ctph0,stph0,tlm0)
use kinds, only: r_kind
+ use constants, only: zero
implicit none
class(get_wrf_binary_interface_class), intent(inout) :: this
logical ,intent(inout) :: update_pint
real(r_kind),intent( out) :: ctph0,stph0,tlm0
+ ctph0 = zero
+ stph0 = zero
+ tlm0 = zero
end subroutine convert_nems_nmmb_dummy
end module get_wrf_binary_interface_mod
diff --git a/src/gsi/stub_wrf_netcdf_interface.f90 b/src/gsi/stub_wrf_netcdf_interface.f90
index d80b765300..4235318686 100644
--- a/src/gsi/stub_wrf_netcdf_interface.f90
+++ b/src/gsi/stub_wrf_netcdf_interface.f90
@@ -30,12 +30,15 @@ end subroutine convert_netcdf_mass_dummy
subroutine convert_netcdf_nmm_dummy(this,update_pint,ctph0,stph0,tlm0,guess)
use kinds, only: r_single,i_kind,r_kind
+ use constants, only: zero
implicit none
class(convert_netcdf_class) ,intent(inout) :: this
logical ,intent(in ) :: guess
logical ,intent(inout) :: update_pint
real(r_kind),intent( out) :: ctph0,stph0,tlm0
-
+ ctph0 = zero
+ stph0 = zero
+ tlm0 = zero
end subroutine convert_netcdf_nmm_dummy
subroutine update_netcdf_mass_dummy(this)
diff --git a/src/gsi/support_2dvar.f90 b/src/gsi/support_2dvar.f90
index 35599ba548..0a83e96942 100644
--- a/src/gsi/support_2dvar.f90
+++ b/src/gsi/support_2dvar.f90
@@ -2465,19 +2465,19 @@ subroutine relocsfcob(rlon8,rlat8,cobtypein,cstationin,kxin)
js=max(1,(jstart-jneighbour))
je=min((jstart+jneighbour),ny)
- ris=float(is)
- rie=float(ie)
- rjs=float(js)
- rje=float(je)
+ ris=real(is,r_single)
+ rie=real(ie,r_single)
+ rjs=real(js,r_single)
+ rje=real(je,r_single)
distmin=1.e+20_r_single
lfound=.false.
do j=1,npts
- rj=rjs+float(j-1)*dy
+ rj=rjs+real(j-1,r_single)*dy
if (rj > rje) cycle
do i=1,npts
- ri=ris+float(i-1)*dx
+ ri=ris+real(i-1,r_single)*dx
if (ri > rie) cycle
call bilinear_2d0(slmask,nx,ny,slmask0,rj,ri)
@@ -2655,7 +2655,7 @@ subroutine mkvalley_file
endif
enddo
enddo
- hmean=hmean/max(1._r_single,float(ncount))
+ hmean=hmean/max(1._r_single,real(ncount,r_single))
if ((hmax-hmin)>=hdiff0 .and. terrain(i,j)0) then
ptr3dges = max(ptr3dges+ptr3dinc,zero)
@@ -454,7 +458,7 @@ subroutine update_guess(sval,sbias)
endif
call gsd_update_soil_tq(tinc_1st,is_t,qinc_1st,is_q,it)
endif ! l_gsd_soilTQ_nudge
- if (i_use_2mt4b > 0 .and. is_t>0) then
+ if ( (i_use_2mt4b > 0.or. hofx_2m_sfcfile) .and. is_t>0) then
do j=1,lon2
do i=1,lat2
tinc_1st(i,j)=p_tv(i,j,1)
@@ -462,7 +466,7 @@ subroutine update_guess(sval,sbias)
end do
call gsd_update_t2m(tinc_1st,it)
endif ! l_gsd_t2m_adjust
- if (i_use_2mq4b > 0 .and. is_q>0) then
+ if ( (i_use_2mq4b > 0.or. hofx_2m_sfcfile) .and. is_q>0) then
do j=1,lon2
do i=1,lat2
qinc_1st(i,j)=p_q(i,j,1)
diff --git a/src/gsi/vqc_int.f90 b/src/gsi/vqc_int.f90
index 714ee23ea3..12abc53b35 100644
--- a/src/gsi/vqc_int.f90
+++ b/src/gsi/vqc_int.f90
@@ -27,12 +27,12 @@ subroutine vqc_int(error2,rat_error2,t_pgv,cg_tv,var_jbv,ibv,ikv,valv,gradv)
real(r_kind), intent(out) :: gradv
! Declare local variables
- real(r_kind) wnotgross,wgross,g_nvqc,w_nvqc,p0,qq
+ real(r_kind) wnotgross,wgross,g_nvqc,w_nvqc,p0,qq
- if (vqc .and. nlnqc_iter .and. t_pgv > tiny_r_kind .and. &
+ if (vqc .and. nlnqc_iter .and. t_pgv > tiny_r_kind .and. &
cg_tv > tiny_r_kind) then
wnotgross= one-t_pgv
wgross =t_pgv*cg_tv/wnotgross
diff --git a/src/gsi/vqc_stp.f90 b/src/gsi/vqc_stp.f90
index 1c8f296853..04d9a91245 100644
--- a/src/gsi/vqc_stp.f90
+++ b/src/gsi/vqc_stp.f90
@@ -41,7 +41,7 @@ subroutine vqc_stp(pen_v,nstep_v,tpg_v,cgt_v,&
! Note: if wgross=0 (no gross error, then wnotgross=1 and this
! all reduces to the linear case (no qc)
- if (vqc .and. nlnqc_iter .and. tpg_v > tiny_r_kind .and. cgt_v >tiny_r_kind) then
+ if (vqc .and. nlnqc_iter .and. tpg_v > tiny_r_kind .and. cgt_v >tiny_r_kind) then
wnotgross= one-tpg_v
wgross =tpg_v*cgt_v/wnotgross
do kk=1,max(1,nstep_v)
diff --git a/src/gsi/wind_fft.f90 b/src/gsi/wind_fft.f90
index 449ceb120a..cc21843d8b 100644
--- a/src/gsi/wind_fft.f90
+++ b/src/gsi/wind_fft.f90
@@ -123,8 +123,8 @@ subroutine divvort_to_psichi(nx0,ny0,mmax0,nmax0,rld0,qg)
pi = four*atan(one)
- xmax = float(nx-1)
- ymax = float(ny-1)
+ xmax = real(nx-1,r_kind)
+ ymax = real(ny-1,r_kind)
! write(6,*) ' in divvort_to_psichi: xmax,ymax,=',xmax,ymax
!
!==> compute trig tables for fft routines.
@@ -134,14 +134,14 @@ subroutine divvort_to_psichi(nx0,ny0,mmax0,nmax0,rld0,qg)
!
!==> set up wavenumbers used in fourier differentiation.
do 100 i=1,nwavesx
- rk(i) = two*pi*float(i-1)/xmax
+ rk(i) = two*pi*real(i-1,r_kind)/xmax
100 continue
ny2 = (ny/2)+1
do 200 j=1,ny
mm = j/ny2
m = mm*ny+1
- wavey = two*pi*float(j-m)/ymax
+ wavey = two*pi*real(j-m,r_kind)/ymax
if (j<=nmax+1 .or. j>=ny-nmax+1) then
indx = j-m+nmax+1
indxy(indx) = j
diff --git a/src/gsi/windht.f90 b/src/gsi/windht.f90
index 09207d38b8..bd685155c4 100644
--- a/src/gsi/windht.f90
+++ b/src/gsi/windht.f90
@@ -139,7 +139,7 @@ subroutine destroy_windht_lists
end subroutine destroy_windht_lists
- subroutine find_wind_height(cprov,csubprov,finalheight)
+ subroutine find_wind_height(cprov,csubprov,finalheight,kcount)
!abstract: Find provider and subprovider in pre-determined arrays
!Then return wind sensor height
@@ -149,6 +149,7 @@ subroutine find_wind_height(cprov,csubprov,finalheight)
character(len=8),intent(in)::cprov,csubprov
real(r_kind),intent(out)::finalheight
+ integer,dimension(3),intent(inout)::kcount
!local vars
integer(i_kind)::i
@@ -156,16 +157,35 @@ subroutine find_wind_height(cprov,csubprov,finalheight)
!sanity check
if (.not.fexist) then
- print*, "WARNING: File containing sensor heights does not exist. Defaulting to 10 m..."
+
+ if(kcount(1) < 10)then
+ print*, "WARNING: File containing sensor heights does not exist. Defaulting to 10 m..."
+ else if(kcount(1) == 10)then
+ print*, "WARNING: List of providers not properly in memory. Defaulting to 10 m..."
+ print*, "Many values see kcount (1) below "
+ end if
+ kcount(1) = kcount(1) + 1
finalheight=r10
return
elseif(.not.listexist) then
- print*, "WARNING: List of providers not properly in memory. Defaulting to 10 m..."
+ if(kcount(2) < 10)then
+ print*, "WARNING: List of providers not properly in memory. Defaulting to 10 m..."
+ else if(kcount(2) == 10)then
+ print*, "WARNING: List of providers not properly in memory. Defaulting to 10 m..."
+ print*, "Many values see kcount (2) below "
+ end if
+ kcount(2) = kcount(2) + 1
finalheight=r10
return
elseif (numprovs>nmax) then
- print*, "WARNING: Invalid number of provider/subprovider combinations (number,max)=",numprovs,nmax
- print*, "WARNING: Defaulting to 10 m wind sensor height!"
+ if(kcount(3) < 10)then
+ print*, "WARNING: Invalid number of provider/subprovider combinations (number,max)=",numprovs,nmax
+ print*, "WARNING: Defaulting to 10 m wind sensor height!"
+ else if(kcount(3) == 10)then
+ print*, "WARNING: Invalid number of provider/subprovider combinations (number,max)=",numprovs,nmax
+ print*, "Many values see kcount (3) below "
+ end if
+ kcount(3) = kcount(3) + 1
finalheight=r10
return
endif
diff --git a/src/gsi/wrf_vars_mod.f90 b/src/gsi/wrf_vars_mod.f90
index 97c36c43cf..f7a5e6c83d 100644
--- a/src/gsi/wrf_vars_mod.f90
+++ b/src/gsi/wrf_vars_mod.f90
@@ -39,6 +39,8 @@ module wrf_vars_mod
use mpimod, only: mype
use control_vectors, only: nc3d,cvars3d
use kinds, only: i_kind
+use gsi_metguess_mod, only: gsi_metguess_get
+use constants, only: max_varname_length
implicit none
private
! public methods
@@ -46,21 +48,54 @@ module wrf_vars_mod
! common block variables
public :: w_exist
public :: dbz_exist
+public :: fed_exist
-logical,save :: w_exist, dbz_exist
+logical,save :: w_exist, dbz_exist, fed_exist
contains
subroutine init_wrf_vars
-integer(i_kind) ii
+integer(i_kind) ii,istatus
+character(max_varname_length),allocatable,dimension(:) :: cloud
+integer(i_kind) ncloud
+logical :: dbz_cloud_exist,fed_cloud_exist
w_exist=.false.
dbz_exist=.false.
+fed_exist=.false.
+dbz_cloud_exist=.false.
+fed_cloud_exist=.false.
+
do ii=1,nc3d
if(mype == 0 ) write(6,*)"anacv cvars3d is ",cvars3d(ii)
if(trim(cvars3d(ii)) == 'w'.or.trim(cvars3d(ii))=='W') w_exist=.true.
if(trim(cvars3d(ii))=='dbz'.or.trim(cvars3d(ii))=='DBZ') dbz_exist=.true.
+ if(trim(cvars3d(ii))=='fed'.or.trim(cvars3d(ii))=='FED') fed_exist=.true.
enddo
+! Inquire about clouds
+
+call gsi_metguess_get('clouds::3d',ncloud,istatus)
+if (ncloud>0) then
+ allocate(cloud(ncloud))
+ call gsi_metguess_get('clouds::3d',cloud,istatus)
+endif
+
+do ii=1,ncloud
+ if(mype == 0 ) write(6,*)"metguess cloud3d is ",cloud(ii)
+ if(trim(cloud(ii))=='fed'.or.trim(cloud(ii))=='FED')fed_cloud_exist=.true.
+ if(trim(cloud(ii))=='dbz'.or.trim(cloud(ii))=='DBZ')dbz_cloud_exist=.true.
+end do
+
+if(.not.fed_exist .or. .not.fed_cloud_exist )then
+ fed_exist=.false.
+endif
+
+if(.not.dbz_exist .or. .not.dbz_cloud_exist )then
+ dbz_exist=.false.
+endif
+
+if(ncloud>0) deallocate(cloud)
+
end subroutine init_wrf_vars
end module wrf_vars_mod
diff --git a/src/gsi/write_fv3_spread.f90 b/src/gsi/write_fv3_spread.f90
index 4baef4c6bd..e1348c9449 100644
--- a/src/gsi/write_fv3_spread.f90
+++ b/src/gsi/write_fv3_spread.f90
@@ -227,10 +227,10 @@ subroutine write_fv3_enspread_ (grdin,filename,en_spread,ibin)
start = (/1/), count = (/grdin%nlon,grdin%nlat/)))
! levels
do k=1,grdin%nsig
- levsout(k) = float(k)
- ilevsout(k) = float(k)
+ levsout(k) = real(k,r_kind)
+ ilevsout(k) = real(k,r_kind)
end do
- ilevsout(grdin%nsig+1) = float(grdin%nsig+1)
+ ilevsout(grdin%nsig+1) = real(grdin%nsig+1,r_kind)
! write to file
call ncceck_enspread(nf90_put_var(ncid_out, levvarid, sngl(levsout), &
start = (/1/), count = (/grdin%nsig/)))
diff --git a/src/gsi/write_incr.f90 b/src/gsi/write_incr.f90
index 69ad96e281..02160c9ccd 100644
--- a/src/gsi/write_incr.f90
+++ b/src/gsi/write_incr.f90
@@ -26,7 +26,7 @@ module write_incr
contains
- subroutine write_fv3_inc_ (grd,sp_a,filename,mype_out,gfs_bundle,ibin)
+ subroutine write_fv3_inc_ (grd,filename,mype_out,gfs_bundle,ibin)
!$$$ subprogram documentation block
! . . .
@@ -76,6 +76,7 @@ subroutine write_fv3_inc_ (grd,sp_a,filename,mype_out,gfs_bundle,ibin)
use general_sub2grid_mod, only: sub2grid_info
use gsi_bundlemod, only: gsi_bundle, gsi_bundlegetpointer
+ use gsi_bundlemod, only: assignment(=)
use control_vectors, only: control_vector
use constants, only: one, rad2deg, r1000
@@ -93,13 +94,14 @@ subroutine write_fv3_inc_ (grd,sp_a,filename,mype_out,gfs_bundle,ibin)
use state_vectors, only: svars3d
use mpeu_util, only: getindex
+ use control2state_mod, only: control2state
+ use ensctl2state_mod, only: ensctl2state
implicit none
! !INPUT PARAMETERS:
type(sub2grid_info), intent(in) :: grd
- type(spec_vars), intent(in) :: sp_a
character(len=24), intent(in) :: filename ! file to open and write to
integer(i_kind), intent(in) :: mype_out ! mpi task to write output file
type(gsi_bundle), intent(in) :: gfs_bundle
@@ -158,7 +160,6 @@ subroutine write_fv3_inc_ (grd,sp_a,filename,mype_out,gfs_bundle,ibin)
! set up state space based off of xhatsave
! Convert from control space directly to physical
! space for comparison with obs.
- call allocate_preds(sbiasinc)
do iii=1,nobs_bins
call allocate_state(svalinc(iii))
end do
@@ -168,7 +169,10 @@ subroutine write_fv3_inc_ (grd,sp_a,filename,mype_out,gfs_bundle,ibin)
do iii=1,ntlevs_ens
call allocate_state(evalinc(iii))
end do
+
+ call allocate_preds(sbiasinc)
call control2state(xhatsave,mvalinc,sbiasinc)
+ call deallocate_preds(sbiasinc)
if (l4dvar) then
if (l_hyb_ens) then
@@ -193,6 +197,12 @@ subroutine write_fv3_inc_ (grd,sp_a,filename,mype_out,gfs_bundle,ibin)
end do
end if
end if
+ do iii=1,ntlevs_ens
+ call deallocate_state(evalinc(iii))
+ end do
+ do iii=1,nsubwin
+ call deallocate_state(mvalinc(iii))
+ end do
! Check hydrometeors in control variables
iql = getindex(svars3d,'ql')
@@ -334,10 +344,10 @@ subroutine write_fv3_inc_ (grd,sp_a,filename,mype_out,gfs_bundle,ibin)
start = (/1/), count = (/grd%nlon/)))
! levels
do k=1,grd%nsig
- levsout(k) = float(k)
- ilevsout(k) = float(k)
+ levsout(k) = real(k,r_kind)
+ ilevsout(k) = real(k,r_kind)
end do
- ilevsout(grd%nsig+1) = float(grd%nsig+1)
+ ilevsout(grd%nsig+1) = real(grd%nsig+1,r_kind)
! write to file
call nccheck_incr(nf90_put_var(ncid_out, levvarid, sngl(levsout), &
start = (/1/), count = (/grd%nsig/)))
@@ -366,10 +376,9 @@ subroutine write_fv3_inc_ (grd,sp_a,filename,mype_out,gfs_bundle,ibin)
ncstart = (/ jstart(mype+1), 1, 1 /)
nccount = (/ grd%lon1, grd%lat1-1, grd%nsig /)
j1 = 2
- j2 = grd%lat1-1
else if (istart(mype+1)+grd%lat1 == grd%nlat+1) then
nccount = (/ grd%lon1, grd%lat1-1, grd%nsig /)
- j2 = grd%lat1-2
+ j2 = grd%lat1-1
end if
call mpi_barrier(mpi_comm_world,ierror)
allocate(out3d(nccount(1),nccount(2),grd%nsig))
@@ -528,6 +537,10 @@ subroutine write_fv3_inc_ (grd,sp_a,filename,mype_out,gfs_bundle,ibin)
endif
! ! cleanup and exit
call nccheck_incr(nf90_close(ncid_out))
+ deallocate(out3d)
+ do iii=1,nobs_bins
+ call deallocate_state(svalinc(iii))
+ end do
if ( mype == mype_out ) then
write(6,*) "FV3 netCDF increment written, file= "//trim(filename)//".nc"
end if
diff --git a/src/gsi/xhat_vordivmod.f90 b/src/gsi/xhat_vordivmod.f90
index bff52aa9d4..e271fb9fb3 100644
--- a/src/gsi/xhat_vordivmod.f90
+++ b/src/gsi/xhat_vordivmod.f90
@@ -77,6 +77,8 @@ subroutine init_
allocate(xhat_vor(lat2,lon2,nsig,nobs_bins))
allocate(xhat_div(lat2,lon2,nsig,nobs_bins))
+ xhat_vor=zero
+ xhat_div=zero
end subroutine init_
subroutine clean_
@@ -146,18 +148,6 @@ subroutine calc_(sval)
!*******************************************************************************
-! Initialize local arrays
- do ii=1,nobs_bins
- do k=1,nsig
- do j=1,lon2
- do i=1,lat2
- xhat_vor(i,j,k,ii) = zero
- xhat_div(i,j,k,ii) = zero
- end do
- end do
- end do
- end do
-
! The GSI analyzes stream function (sf) and velocity potential (vp).
! Wind field observations are in terms of zonal (u) and meridional
! (v) wind components or wind speed. Thus, the GSI carries wind
diff --git a/src/mgbf/CMakeLists.txt b/src/mgbf/CMakeLists.txt
new file mode 100644
index 0000000000..9ee36c8329
--- /dev/null
+++ b/src/mgbf/CMakeLists.txt
@@ -0,0 +1,98 @@
+cmake_minimum_required(VERSION 3.15)
+
+project(mgbf
+ VERSION 1.0.0
+ LANGUAGES Fortran)
+
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+set(CMAKE_DIRECTORY_LABELS ${PROJECT_NAME})
+
+include(GNUInstallDirs)
+
+if(NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)$")
+ message(STATUS "Setting build type to 'Release' as none was specified.")
+ set(CMAKE_BUILD_TYPE
+ "Release"
+ CACHE STRING "Choose the type of build." FORCE)
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
+endif()
+
+if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "^(GNU|Intel)$")
+ message(WARNING "${CMAKE_Fortran_COMPILER_ID} is not supported.")
+endif()
+
+if(CMAKE_Fortran_COMPILER_ID MATCHES "^(Intel)$")
+ set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -traceback -convert big_endian")
+elseif(CMAKE_Fortran_COMPILER_ID MATCHES "^(GNU)$")
+ set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -fbacktrace -fconvert=big-endian")
+endif()
+
+if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
+ add_definitions(-DNDEBUG)
+endif()
+
+list(APPEND MGBF_SRC
+kinds.f90
+jp_pkind.f90
+jp_pkind2.f90
+jp_pietc.f90
+jp_pietc_s.f90
+jp_pmat.f90
+jp_pmat4.f90
+jp_pbfil.f90
+jp_pbfil2.f90
+jp_pbfil3.f90
+mg_mppstuff.f90
+mg_domain.f90
+mg_domain_loc.f90
+mg_parameter.f90
+mg_bocos.f90
+mg_transfer.f90
+mg_generations.f90
+mg_interpolate.f90
+mg_filtering.f90
+mg_timers.f90
+mg_entrymod.f90
+mg_intstate.f90
+mg_input.f90
+)
+
+set(module_dir "${CMAKE_CURRENT_BINARY_DIR}/include/mgbf")
+add_library(mgbf STATIC ${MGBF_SRC})
+add_library(${PROJECT_NAME}::mgbf ALIAS mgbf)
+set_target_properties(mgbf PROPERTIES Fortran_MODULE_DIRECTORY "${module_dir}")
+target_include_directories(mgbf PUBLIC $
+ $)
+
+install(DIRECTORY ${module_dir} DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
+
+install(TARGETS mgbf
+ EXPORT ${PROJECT_NAME}Exports
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+# Package config
+include(CMakePackageConfigHelpers)
+set(CONFIG_INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
+
+export(EXPORT ${PROJECT_NAME}Exports
+ NAMESPACE ${PROJECT_NAME}::
+ FILE ${PROJECT_NAME}-targets.cmake)
+
+configure_package_config_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/PackageConfig.cmake.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config.cmake
+ INSTALL_DESTINATION ${CONFIG_INSTALL_DESTINATION})
+install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config.cmake
+ DESTINATION ${CONFIG_INSTALL_DESTINATION})
+
+write_basic_package_version_file(
+ ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
+ VERSION ${PROJECT_VERSION}
+ COMPATIBILITY AnyNewerVersion)
+install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
+ DESTINATION ${CONFIG_INSTALL_DESTINATION})
+
+install(EXPORT ${PROJECT_NAME}Exports
+ NAMESPACE ${PROJECT_NAME}::
+ FILE ${PROJECT_NAME}-targets.cmake
+ DESTINATION ${CONFIG_INSTALL_DESTINATION})
diff --git a/src/mgbf/cmake/PackageConfig.cmake.in b/src/mgbf/cmake/PackageConfig.cmake.in
new file mode 100644
index 0000000000..e64cb4ef87
--- /dev/null
+++ b/src/mgbf/cmake/PackageConfig.cmake.in
@@ -0,0 +1,19 @@
+@PACKAGE_INIT@
+
+#@PROJECT_NAME@-config.cmake
+#
+# Imported interface targets provided:
+# * @PROJECT_NAME@::MGBF - MGBF library target
+
+# Include targets file. This will create IMPORTED target @PROJECT_NAME@
+include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-config-version.cmake")
+include(CMakeFindDependencyMacro)
+
+# Get the build type from library target
+get_target_property(@PROJECT_NAME@_BUILD_TYPES @PROJECT_NAME@::@PROJECT_NAME@ IMPORTED_CONFIGURATIONS)
+
+check_required_components("@PROJECT_NAME@")
+
+get_target_property(location @PROJECT_NAME@::@PROJECT_NAME@ LOCATION)
+message(STATUS "Found @PROJECT_NAME@: ${location} (found version \"${PACKAGE_VERSION}\")")
diff --git a/src/mgbf/jp_pbfil.f90 b/src/mgbf/jp_pbfil.f90
new file mode 100644
index 0000000000..89a9196596
--- /dev/null
+++ b/src/mgbf/jp_pbfil.f90
@@ -0,0 +1,1119 @@
+submodule(mg_parameter) jp_pbfil
+!$$$ submodule documentation block
+! . . . .
+! module: jp_pbfil
+! prgmmr: purser org: NOAA/EMC date: 2019-03
+!
+! abstract: Codes for the beta filters
+!
+! module history log:
+! 2023-04-19 lei - object-oriented coding
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! cholaspect1 -
+! cholaspect2 -
+! cholaspect3 -
+! cholaspect4 -
+! getlinesum1 -
+! getlinesum2 -
+! getlinesum3 -
+! getlinesum4 -
+! rbeta1 -
+! rbeta2 -
+! rbeta3 -
+! rbeta4 -
+! vrbeta4 -
+! rbeta1T -
+! rbeta2T -
+! rbeta3T -
+! rbeta4T -
+! vrbeta4t -
+! vrbeta1 -
+! vrbeta2 -
+! vrbeta3 -
+! vrbeta1T -
+! vrbeta2T -
+! vrbeta3T -
+!
+! Functions Included:
+!
+! remarks:
+! The filters invoke the aspect tensor information encoded by the
+! Cholesky lower-triangular factors, el, of the INVERSE aspect tensors.
+! The routines, "cholaspect", convert (in place) the field of given
+! aspect tensors A to the equivalent cholesky factors of A^(-1).
+! The routines, "getlinesum" precompute the normalization coefficients
+! for each line (row) of the implied matrix form of the beta filter
+! so that the normalized line sum associated with each point of
+! application becomes unity.
+! This makes the application of each filter significantly faster
+! than having to work out the normalization on the fly.
+! Be sure to have run cholaspect, and then getlinesum, prior to applying
+! the beta filters themselves.
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+use kinds, only: dp=>r_kind
+use jp_pietc, only: u1
+implicit none
+
+contains
+
+!=============================================================================
+module subroutine cholaspect1(lx,mx, el) ! [cholaspect]
+!=============================================================================
+! Convert the given field, el, of aspect tensors into the equivalent
+! field
+! of Cholesky lower-triangular factors of the inverses of the aspect
+! tensors.
+!=============================================================================
+use jp_pmat, only: inv, l1lm
+integer, intent(in ):: lx,mx
+real(dp),dimension(1,1,lx:mx),intent(inout):: el
+!-----------------------------------------------------------------------------
+integer :: ix
+!=============================================================================
+do ix=lx,mx; el(1,1,ix)=u1/sqrt(el(1,1,ix)); enddo
+end subroutine cholaspect1
+!=============================================================================
+module subroutine cholaspect2(lx,mx, ly,my, el) ! [cholaspect]
+!=============================================================================
+! Convert the given field, el, of aspect tensors into the equivalent
+! field
+! of Cholesky lower-triangular factors of the inverses of the aspect
+! tensors.
+!=============================================================================
+use jp_pmat, only: inv, l1lm
+integer, intent(in ):: lx,mx, ly,my
+real(dp),dimension(2,2,lx:mx,ly:my),intent(inout):: el
+!-----------------------------------------------------------------------------
+real(dp),dimension(2,2):: tel
+integer :: ix,iy
+!=============================================================================
+do iy=ly,my; do ix=lx,mx
+ tel=el(:,:,ix,iy); call inv(tel); call l1lm(tel,el(:,:,ix,iy))
+enddo; enddo
+end subroutine cholaspect2
+!=============================================================================
+module subroutine cholaspect3(lx,mx, ly,my, lz,mz, el) ! [cholaspect]
+!=============================================================================
+! Convert the given field, el, of aspect tensors into the equivalent
+! field
+! of Cholesky lower-triangular factors of the inverses of the aspect
+! tensors.
+!=============================================================================
+use jp_pmat, only: inv, l1lm
+integer, intent(in ):: lx,mx, ly,my, lz,mz
+real(dp),dimension(3,3,lx:mx,ly:my,lz:mz),intent(inout):: el
+!-----------------------------------------------------------------------------
+real(dp),dimension(3,3):: tel
+integer :: ix,iy,iz
+!=============================================================================
+do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ tel=el(:,:,ix,iy,iz); call inv(tel); call l1lm(tel,el(:,:,ix,iy,iz))
+enddo; enddo; enddo
+end subroutine cholaspect3
+!=============================================================================
+module subroutine cholaspect4(lx,mx, ly,my, lz,mz, lw,mw,el) ! [cholaspect]
+!=============================================================================
+! Convert the given field, el, of aspect tensors into the equivalent
+! field
+! of Cholesky lower-triangular factors of the inverses of the aspect
+! tensors.
+!=============================================================================
+use jp_pmat, only: inv, l1lm
+integer, intent(in ):: lx,mx, ly,my, lz,mz, lw,mw
+real(dp),dimension(4,4,lx:mx,ly:my,lz:mz,lw:mw),&
+ intent(inout):: el
+!-----------------------------------------------------------------------------
+real(dp),dimension(4,4):: tel
+integer :: ix,iy,iz,iw
+!=============================================================================
+do iw=lw,mw; do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ tel=el(:,:,ix,iy,iz,iw); call inv(tel); call l1lm(tel,el(:,:,ix,iy,iz,iw))
+enddo; enddo; enddo; enddo
+end subroutine cholaspect4
+
+!=============================================================================
+module subroutine getlinesum1(this,hx,lx,mx, el, ss) ! [getlinesum]
+!=============================================================================
+! Get inverse of the line-sum of the matrix representing the
+! unnormalized
+! beta function with aspect tensor pasp=(el*el^T)^(-1), and invert the
+! result
+! so it can be used subsequently in the normalized version of this
+! filter.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx
+real(dp),dimension(1,1,Lx:Mx),intent(in ):: el
+real(dp),dimension(lx:mx),intent( out):: ss
+!-----------------------------------------------------------------------------
+real(dp),parameter:: eps=1.e-12
+real(dp) :: s,rr,rrc,exx,x
+integer :: ix,gxl,gxm,gx
+!=============================================================================
+do ix=Lx,Mx
+ s=0
+ exx=el(1,1,ix)*this%rmom2_1
+ x=u1/exx
+ gxl=ceiling(-x+eps); gxm=floor( x-eps)
+ if(gxl<-hx.or.gxm>hx)&
+ stop 'In getlinesum1; filter reach fx becomes too large for hx'
+ do gx=gxl,gxm
+ x=gx
+ rr=(x*exx)**2; rrc=u1-rr
+ s=s+rrc**this%p
+ enddo
+ ss(ix)=u1/s
+enddo
+end subroutine getlinesum1
+!=============================================================================
+module subroutine getlinesum2(this,hx,lx,mx, hy,ly,my, el, ss) ! [getlinesum]
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx, &
+ hy,ly,my
+real(dp),dimension(2,2,Lx:Mx,Ly:My),intent(in ):: el
+real(dp),dimension( lx:mx,ly:my),intent( out):: ss
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(2,2):: tel
+real(dp) :: s,rr,rrx,rrc,exx,eyy,eyx,x,y,xc
+integer :: ix,gx,gxl,gxm
+integer :: iy,gy,gyl,gym
+!=============================================================================
+do iy=Ly,My; do ix=Lx,Mx
+ s=0
+ tel=el(:,:,ix,iy)*this%rmom2_2 ! This el, rescaled
+ exx=tel(1,1); eyy=tel(2,2)
+ eyx=tel(2,1)
+ y=u1/eyy
+ gyl=ceiling(-y+eps); gym=floor( y-eps)
+ if(gyl<-hy.or.gym>hy)&
+ stop 'In getlinesum2; filter reach becomes too large for hy'
+ do gy=gyl,gym
+ y=gy; xc=-y*eyx
+ rrx=(y*eyy)**2; x=sqrt(u1-rrx)
+ gxl=ceiling((xc-x)/exx+eps); gxm=floor((xc+x)/exx-eps)
+ if(gxl<-hx.or.gxm>hx)&
+ stop 'In getlinesum2; filter reach becomes too large for hx'
+ do gx=gxl,gxm
+ x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ s=s+rrc**this%p
+ enddo! gx
+ enddo! gy
+ ss(ix,iy)=u1/s
+enddo; enddo! ix, iy
+end subroutine getlinesum2
+!=============================================================================
+module subroutine getlinesum3(this,hx,lx,mx, hy,ly,my, hz,lz,mz, el, ss) ! [getlinesum]
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx, &
+ hy,ly,my, &
+ hz,lz,mz
+real(dp),dimension(3,3,Lx:Mx,Ly:My,Lz:Mz),intent(in ):: el
+real(dp),dimension( lx:mx,ly:my,lz:mz),intent( out):: ss
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(3,3):: tel
+real(dp) :: s,rr,rrx,rry,rrc,&
+ exx,eyy,ezz,eyx,ezx,ezy, x,y,z,xc,yc
+integer :: ix,gx,gxl,gxm
+integer :: iy,gy,gyl,gym
+integer :: iz,gz,gzl,gzm
+!=============================================================================
+ss=0
+do iz=Lz,Mz; do iy=Ly,My; do ix=Lx,Mx
+ s=0
+ tel=el(:,:,ix,iy,iz)*this%rmom2_3
+ exx=tel(1,1); eyy=tel(2,2); ezz=tel(3,3)
+ eyx=tel(2,1); ezx=tel(3,1)
+ ezy=tel(3,2)
+ z=u1/ezz
+ gzl=ceiling(-z+eps); gzm=floor( z-eps)
+ if(gzl<-hz.or.gzm>hz)&
+ stop 'In getlinesum3; filter reach becomes too large for hz'
+ do gz=gzl,gzm
+ z=gz; yc=-z*ezy
+ rry=(z*ezz)**2; y =sqrt(u1-rry)
+ gyl=ceiling((yc-y)/eyy+eps); gym=floor((yc+y)/eyy-eps)
+ if(gyl<-hy.or.gym>hy)&
+ stop 'In getlinesum3; filter reach becomes too large for hy'
+ do gy=gyl,gym
+ y=gy; xc=-y*eyx-z*ezx
+ rrx=rry+(y*eyy-yc)**2; x =sqrt(u1-rrx)
+ gxl=ceiling((xc-x)/exx+eps); gxm=floor((xc+x)/exx-eps)
+ if(gxl<-hx.or.gxm>hx)&
+ stop 'In getlinesum3; filter reach becomes too large for hx'
+ do gx=gxl,gxm
+ x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ s=s+rrc**this%p
+ enddo! gx
+ enddo! gy
+ enddo! gz
+ ss(ix,iy,iz)=u1/s
+enddo; enddo; enddo! ix, iy, iz
+end subroutine getlinesum3
+!=============================================================================
+module subroutine getlinesum4(this,hx,lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw, &
+ el, ss) ! [getlinesum]
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx, &
+ hy,ly,my, &
+ hz,lz,mz, &
+ hw,lw,mw
+real(dp),dimension(4,4,Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: el
+real(dp),dimension( lx:mx,ly:my,lz:mz,Lw:Mw),intent( out):: ss
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(4,4):: tel
+real(dp) :: s,rr,rrx,rry,rrz,rrc, &
+ exx,eyy,ezz,eww,eyx,ezx,ewx,ezy,ewy,ewz, x,y,z,w,&
+ xc,yc,zc
+integer :: ix,gx,gxl,gxm
+integer :: iy,gy,gyl,gym
+integer :: iz,gz,gzl,gzm
+integer :: iw,gw,gwl,gwm
+!=============================================================================
+ss=0
+do iw=Lw,Mw; do iz=Lz,Mz; do iy=Ly,My; do ix=Lx,Mx
+ s=0
+ tel=el(:,:,ix,iy,iz,iw)*this%rmom2_4
+ exx=tel(1,1); eyy=tel(2,2); ezz=tel(3,3); eww=tel(4,4)
+ eyx=tel(2,1); ezx=tel(3,1); ewx=tel(4,1)
+ ezy=tel(3,2); ewy=tel(4,2)
+ ewz=tel(4,3)
+ w=u1/eww
+ gwl=ceiling(-w+eps); gwm=floor( w-eps)
+ if(gwl<-hw.or.gwm>hw)&
+ stop 'In getlinesum4; filter reach becomes too large for hw'
+ do gw=gwl,gwm
+ w=gw; zc=-w*ewz
+ rrz=(w-eww)**2; z =sqrt(u1-rrz)
+ gzl=ceiling((zc-z)/ezz+eps); gzm=floor((zc+z)/ezz-eps)
+ if(gzl<-hz.or.gzm>hz)&
+ stop 'In getlinesum4; filter reach becomes too large for hz'
+ do gz=gzl,gzm
+ z=gz; yc=-z*ezy-w*ewy
+ rry=rrz+(z*ezz-zc)**2; y =sqrt(u1-rry)
+ gyl=ceiling((yc-y)/eyy+eps); gym=floor((yc+y)/eyy-eps)
+ if(gyl<-hy.or.gym>hy)&
+ stop 'In getlinesum4; filter reach becomes too large for hy'
+ do gy=gyl,gym
+ y=gy; xc=-y*eyx-z*ezx-w*ewx
+ rrx=rry+(y*eyy-yc)**2; x =sqrt(u1-rrx)
+ gxl=ceiling((xc-x)/exx+eps); gxm=floor((xc+x)/exx-eps)
+ if(gxl<-hx.or.gxm>hx)&
+ stop 'In getlinesum4; filter reach becomes too large for hx'
+ do gx=gxl,gxm
+ x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ s=s+rrc**this%p
+ enddo! gx
+ enddo! gy
+ enddo! gz
+ enddo! gw
+ ss(ix,iy,iz,iw)=u1/s
+enddo; enddo; enddo; enddo! ix, iy, iz, iw
+end subroutine getlinesum4
+
+!=============================================================================
+module subroutine rbeta1(this,hx,lx,mx, el,ss, a) ! [rbeta]
+!=============================================================================
+! Perform a radial beta-function filter in 1D.
+! It averages the surrounding density values, and so preserves the value
+! (in its target region) when presented with a constant-density input
+! field.
+! The input data occupy the extended region:
+! Lx-hx <= jx <= mx+hx.
+! The output data occupy the central region
+! Lx <= ix <= Mx.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx
+real(dp),dimension( Lx:Mx), intent(in ):: el
+real(dp),dimension( Lx:Mx), intent(in ):: ss
+real(dp),dimension(lx-hx:mx+hx),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(lx-hx:mx+hx):: b
+real(dp) :: x,tb,s,rr,rrc,frow,exx
+integer :: ix,jx,gx
+!=============================================================================
+b=0
+do ix=Lx,Mx
+ tb=0; s=ss(ix)
+ exx=el(ix)*this%rmom2_1
+ x=u1/exx
+ do gx=ceiling(-x+eps),floor( x-eps)
+ jx=ix+gx; x=gx
+ rr=(x*exx)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ tb=tb+frow*a(jx)
+ enddo
+ b(ix)=tb
+enddo
+a=b
+end subroutine rbeta1
+!=============================================================================
+module subroutine rbeta2(this,hx,lx,mx, hy,ly,my, el,ss, a) ! [rbeta]
+!=============================================================================
+! Perform a radial beta-function filter in 2D.
+! It averages the surrounding density values, and so preserves the value
+! (in its target region) when presented with a constant-density input
+! field.
+! The input data occupy the extended region:
+! Lx-hx <= jx <= mx+hx, Ly-hy <= Jy <= my+hy
+! The output data occupy the central region
+! Lx <= ix <= Mx, Ly <= iy <= My.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx, &
+ hy,ly,my
+real(dp),dimension(2,2,Lx:Mx,Ly:My), intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My), intent(in ):: ss
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy):: b
+real(dp),dimension(2,2) :: tel
+real(dp) :: tb,s,rr,rrx,rrc,&
+ frow,exx,eyy,eyx,x,y,xc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+!=============================================================================
+b=0
+do iy=Ly,My; do ix=Lx,Mx
+ tb=0; s=ss(ix,iy)
+ tel=el(:,:,ix,iy)*this%rmom2_2 ! This el, rescaled
+ exx=tel(1,1); eyy=tel(2,2)
+ eyx=tel(2,1)
+ y=u1/eyy
+ do gy=ceiling(-y+eps),floor( y-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx
+ rrx=(y*eyy)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ tb=tb+frow*a(jx,jy)
+ enddo! gx
+ enddo! gy
+ b(ix,iy)=tb
+enddo; enddo! ix, iy
+a=b
+end subroutine rbeta2
+!=============================================================================
+module subroutine rbeta3(this,hx,lx,mx, hy,ly,my, hz,lz,mz, el,ss,a) ! [rbeta]
+!=============================================================================
+! Perform a radial beta-function filter in 3D.
+! It averages the surrounding density values, and so preserves the value
+! (in its target region) when presented with a constant-density input
+! field.
+! The input data occupy the extended region:
+! Lx-hx <= jx <= mx+hx, Ly-hy <= Jy <= my+hy, Lz-hz <= Jz <= mz+hz
+! The output data occupy the central region
+! Lx <= ix <= Mx, Ly <= iy <= My, Lz <= iz <= Mz.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx,&
+ hy,ly,my,&
+ hz,lz,mz
+real(dp),dimension(3,3,Lx:Mx,Ly:My,Lz:Mz), intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz), intent(in ):: ss
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy,&
+ lz-hz:mz+hz),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy,lz-hz:mz+hz):: b
+real(dp),dimension(3,3) :: tel
+real(dp):: s,tb,rr,rrx,rry,rrc,frow,&
+ exx,eyy,ezz,eyx,ezx,ezy,x,y,z,xc,yc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+integer :: iz,jz,gz
+!=============================================================================
+b=0
+do iz=Lz,Mz; do iy=Ly,My; do ix=Lx,Mx
+ tb=0; s=ss(ix,iy,iz)
+ tel=el(:,:,ix,iy,iz)*this%rmom2_3
+ exx=tel(1,1); eyy=tel(2,2); ezz=tel(3,3)
+ eyx=tel(2,1); ezx=tel(3,1); ezy=tel(3,2)
+ z=u1/ezz
+ do gz=ceiling(-z+eps),floor( z-eps)
+ jz=iz+gz; z=gz; yc=-z*ezy
+ rry=(z*ezz)**2; y =sqrt(u1-rry)
+ do gy=ceiling((yc-y)/eyy+eps),floor((yc+y)/eyy-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx-z*ezx
+ rrx=rry+(y*eyy-yc)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ tb=tb+frow*a(jx,jy,jz)
+ enddo! gx
+ enddo! gy
+ enddo! gz
+ b(ix,iy,iz)=tb
+enddo; enddo; enddo! ix, iy, iz
+a=b
+end subroutine rbeta3
+!=============================================================================
+module subroutine rbeta4(this,hx,lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw, el,ss,a) ! [rbeta]
+!=============================================================================
+! Perform a radial beta-function filter in 4D.
+! It averages the surrounding density values, and so preserves the value
+! (in its target region) when presented with a constant-density input
+! field.
+! The input data occupy the extended region:
+! Lx-hx <= jx <= mx+hx, Ly-hy <= Jy <= my+hy, Lz-hz <= Jz <= mz+hz,
+! Lw-hw <= Jw <= mw+hw
+! The output data occupy the central region
+! Lx <= ix <= Mx, Ly <= iy <= My, Lz <= iz <= Mz, Lw <= iw <= Mw.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx,&
+ hy,ly,my,&
+ hz,lz,mz,&
+ hw,lw,mw
+real(dp),dimension(4,4,Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: ss
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy, &
+ lz-hz:mz+hz,lw-hw:mw+hw), intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy,&
+ lz-hz:mz+hz,lw-hw:mw+hw) :: b
+real(dp),dimension(4,4) :: tel
+real(dp):: s,tb,rr,rrx,rry,rrz,rrc,frow,&
+ exx,eyy,ezz,eww,eyx,ezx,ewx,ezy,ewy,ewz,x,y,z,w,xc,yc,zc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+integer :: iz,jz,gz
+integer :: iw,jw,gw
+!=============================================================================
+b=0
+do iw=lw,mw; do iz=Lz,Mz; do iy=Ly,My; do ix=Lx,Mx
+ tb=0; s=ss(ix,iy,iz,iw)
+ tel=el(:,:,ix,iy,iz,iw)*this%rmom2_4
+ exx=tel(1,1); eyy=tel(2,2); ezz=tel(3,3); eww=tel(4,4)
+ eyx=tel(2,1); ezx=tel(3,1); ewx=tel(4,1)
+ ezy=tel(3,2); ewy=tel(4,2)
+ ewz=tel(4,3)
+ w=u1/eww
+ do gw=ceiling(-w+eps),floor( w-eps)
+ jw=iw+gw; w=gw; zc=-w*ewz
+ rrz=(w*eww)**2; z =sqrt(u1-rrz)
+ do gz=ceiling((zc-z)/ezz+eps),floor((zc+z)/ezz-eps)
+ jz=iz+gz; z=gz; yc=-z*ezy-w*ewy
+ rry=rrz+(z*ezz-zc)**2; y =sqrt(u1-rry)
+ do gy=ceiling((yc-y)/eyy+eps),floor((yc+y)/eyy-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx-z*ezx-w*ewx
+ rrx=rry+(y*eyy-yc)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ tb=tb+frow*a(jx,jy,jz,jw)
+ enddo! gx
+ enddo! gy
+ enddo! gz
+ enddo! gw
+ b(ix,iy,iz,iw)=tb
+enddo; enddo; enddo; enddo! ix, iy, iz, iw
+a=b
+end subroutine rbeta4
+
+!=============================================================================
+! Vector versions of the above routines:
+!=============================================================================
+module subroutine vrbeta4(this,nv,hx,lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw, &
+ el,ss,a) ! [rbeta]
+!=============================================================================
+! Vector version of rbeta4 filtering nv fields at once.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: nv, &
+ hx,Lx,mx,&
+ hy,ly,my,&
+ hz,lz,mz,&
+ hw,lw,mw
+real(dp),dimension(4,4,Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: ss
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy, &
+ lz-hz:mz+hz,lw-hw:mw+hw), intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy,&
+ lz-hz:mz+hz,lw-hw:mw+hw) :: b
+real(dp),dimension(nv) :: tb
+real(dp),dimension(4,4) :: tel
+real(dp):: s,rr,rrx,rry,rrz,rrc,frow,&
+ exx,eyy,ezz,eww, eyx,ezx,ewx, ezy,ewy, ewz,&
+ x,y,z,w,xc,yc,zc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+integer :: iz,jz,gz
+integer :: iw,jw,gw
+!=============================================================================
+b=0
+do iw=lw,mw; do iz=Lz,Mz; do iy=Ly,My; do ix=Lx,Mx
+ tb=0; s=ss(ix,iy,iz,iw)
+ tel=el(:,:,ix,iy,iz,iw)*this%rmom2_4
+ exx=tel(1,1); eyy=tel(2,2); ezz=tel(3,3); eww=tel(4,4)
+ eyx=tel(2,1); ezx=tel(3,1); ewx=tel(4,1)
+ ezy=tel(3,2); ewy=tel(4,2)
+ ewz=tel(4,3)
+ w=u1/eww
+ do gw=ceiling(-w+eps),floor( w-eps)
+ jw=iw+gw; w=gw; zc=-w*ewz
+ rrz=(w*eww)**2; z =sqrt(u1-rrz)
+ do gz=ceiling((zc-z)/ezz+eps),floor((zc+z)/ezz-eps)
+ jz=iz+gz; z=gz; yc=-z*ezy-w*ewy
+ rry=rrz+(z*ezz-zc)**2; y =sqrt(u1-rry)
+ do gy=ceiling((yc-y)/eyy+eps),floor((yc+y)/eyy-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx-z*ezx-w*ewx
+ rrx=rry+(y*eyy-yc)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ tb=tb+frow*a(:,jx,jy,jz,jw)
+ enddo! gx
+ enddo! gy
+ enddo! gz
+ enddo! gw
+ b(:,ix,iy,iz,iw)=tb
+enddo; enddo; enddo; enddo! ix, iy, iz, iw
+a=b
+end subroutine vrbeta4
+
+!=============================================================================
+module subroutine rbeta1T(this,hx,lx,mx, el,ss, a) ! [rbetat]
+!=============================================================================
+! Perform an ADJOINT radial beta-function filter in 1D.
+! It conserves "masses" initially distributed only at the closure of
+! the central domain,
+! Lx <= ix <= Mx.
+! The output field of the redistributed masses occupies the
+! the extended domain,
+! Lx-hx <= jx <= mx+hx.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx
+real(dp),dimension(1,1,Lx:Mx), intent(in ):: el
+real(dp),dimension( Lx:Mx), intent(in ):: ss
+real(dp),dimension(lx-hx:mx+hx),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(lx-hx:mx+hx):: b
+real(dp) :: ta,s,rr,rrc,frow,exx,x
+integer :: ix,jx,gx
+!=============================================================================
+b=0
+do ix=Lx,Mx
+ ta=a(ix); s=ss(ix)
+ exx=el(1,1,ix)*this%rmom2_1
+ x=u1/exx
+ do gx=ceiling(-x+eps),floor( x-eps)
+ jx=ix+gx; x=gx
+ rr=(x*exx)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ b(jx)=b(jx)+frow*ta
+ enddo
+enddo
+a=b
+end subroutine rbeta1t
+!=============================================================================
+module subroutine rbeta2T(this,hx,lx,mx, hy,ly,my, el,ss, a) ! [rbetat]
+!=============================================================================
+! Perform an ADJOINT radial beta-function filter in 2D.
+! It conserved "masses" initially distributed only at the closure of
+! the central domain,
+! Lx <= ix <= Mx, Ly <= iy <= My.
+! The output field of the redistributed masses occupies the
+! the extended domain,
+! Lx-hx <= jx <= mx+hx, Ly-hy <= Jy <= my+hy
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx, &
+ hy,ly,my
+real(dp),dimension(2,2,Lx:Mx,Ly:My), intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My), intent(in ):: ss
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy):: b
+real(dp),dimension(2,2) :: tel
+real(dp) :: ta,s,rr,rrx,rrc, &
+ frow,exx,eyy,eyx,x,y,xc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+!=============================================================================
+b=0
+do iy=Ly,My; do ix=Lx,Mx
+ ta=a(ix,iy); s=ss(ix,iy)
+ tel=el(:,:,ix,iy)*this%rmom2_2 ! sThis el, rescaled
+ exx=tel(1,1); eyy=tel(2,2)
+ eyx=tel(2,1)
+ y=u1/eyy
+ do gy=ceiling(-y+eps),floor( y-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx
+ rrx=(y*eyy)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ b(jx,jy)=b(jx,jy)+frow*ta
+ enddo! gx
+ enddo! gy
+enddo; enddo! ix, iy
+a=b
+end subroutine rbeta2t
+!=============================================================================
+module subroutine rbeta3T(this,hx,lx,mx, hy,ly,my, hz,lz,mz, el,ss, a) ! [rbetat]
+!=============================================================================
+! Perform an ADJOINT radial beta-function filter in 3D.
+! It conserves "masses" initially distributed only at the closure of
+! the central domain,
+! Lx <= ix <= Mx, Ly <= iy <= My, Lz <= iz <= Mz.
+! The output field of the redistributed masses occupies the
+! the extended domain,
+! Lx-hx <= jx <= Mx+hx, Ly-hy <= Jy <= My+hy, Lz-hz <= Jz <= Mz+hz.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx,&
+ hy,ly,my,&
+ hz,lz,mz
+real(dp),dimension(3,3,Lx:Mx,Ly:My,Lz:Mz), intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz), intent(in ):: ss
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy,&
+ lz-hz:mz+hz),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy,lz-hz:mz+hz):: b
+real(dp),dimension(3,3) :: tel
+real(dp):: ta,s,rr,rrx,rry,rrc,frow,&
+ exx,eyy,ezz,eyx,ezx,ezy,x,y,z,xc,yc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+integer :: iz,jz,gz
+!=============================================================================
+b=0
+do iz=Lz,Mz; do iy=Ly,My; do ix=Lx,Mx
+ ta=a(ix,iy,iz); s=ss(ix,iy,iz)
+ tel=el(:,:,ix,iy,iz)*this%rmom2_3
+ exx=tel(1,1); eyy=tel(2,2); ezz=tel(3,3)
+ eyx=tel(2,1); ezx=tel(3,1); ezy=tel(3,2)
+ z=u1/ezz
+ do gz=ceiling(-z+eps),floor( z-eps)
+ jz=iz+gz; z=gz; yc=-z*ezy
+ rry=(z*ezz)**2; y =sqrt(u1-rry)
+ do gy=ceiling((yc-y)/eyy+eps),floor((yc+y)/eyy-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx-z*ezx
+ rrx=rry+(y*eyy-yc)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ b(jx,jy,jz)=b(jx,jy,jz)+frow*ta
+ enddo! gx
+ enddo! gy
+ enddo ! gz
+enddo; enddo; enddo ! ix, iy, iz
+a=b
+end subroutine rbeta3t
+!=============================================================================
+module subroutine rbeta4T(this,hx,lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw, &
+ el,ss, a) ! [rbetat]
+!=============================================================================
+! Perform an ADJOINT radial beta-function filter in 4D.
+! It conserves "masses" initially distributed only at the closure of
+! the central domain,
+! Lx <= ix <= Mx, Ly <= iy <= My, Lz <= iz <= Mz, Lw <= iw <= Mw.
+! The output field of the redistributed masses occupies the
+! the extended domain,
+! Lx-hx <= jx <= Mx+hx, Ly-hy <= Jy <= My+hy, Lz-hz <= Jz <= Mz+hz,
+! Lw-hw <= Jw <= Mw+hw.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: hx,Lx,mx,&
+ hy,ly,my,&
+ hz,lz,mz,&
+ hw,lw,mw
+real(dp),dimension(4,4,Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: ss
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy,&
+ lz-hz:mz+hz,lw-hw:mw+hw), intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy,&
+ lz-hz:mz+hz,lw-hw:mw+hw) :: b
+real(dp),dimension(4,4) :: tel
+real(dp):: ta,s,rr,rrx,rry,rrz,rrc,frow,&
+ exx,eyy,ezz,eww,eyx,ezx,ewx,ezy,ewy,ewz,x,y,z,w,xc,yc,zc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+integer :: iz,jz,gz
+integer :: iw,jw,gw
+!=============================================================================
+b=0
+do iw=Lw,Mw; do iz=Lz,Mz; do iy=Ly,My; do ix=Lx,Mx
+ ta=a(ix,iy,iz,iw); s=ss(ix,iy,iz,iw)
+ tel=el(:,:,ix,iy,iz,iw)*this%rmom2_4
+ exx=tel(1,1); eyy=tel(2,2); ezz=tel(3,3); eww=tel(4,4)
+ eyx=tel(2,1); ezx=tel(3,1); ewx=tel(4,1)
+ ezy=tel(3,2); ewy=tel(4,2)
+ ewz=tel(4,3)
+ z=u1/ezz
+ do gw=ceiling(-w+eps),floor( w-eps)
+ jw=iw+gw; w=gw; zc=-w*ewz
+ rrz=(w*eww)**2; z =sqrt(u1-rrz)
+ do gz=ceiling((zc-z)/ezz+eps),floor((zc+z)/ezz-eps)
+ jz=iz+gz; z=gz; yc=-z*ezy-w*ewy
+ rry=rrz+(z*ezz-zc)**2; y =sqrt(u1-rry)
+ do gy=ceiling((yc-y)/eyy+eps),floor((yc+y)/eyy-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx-z*ezx-w*ewx
+ rrx=rry+(y*eyy-yc)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ b(jx,jy,jz,jw)=b(jx,jy,jz,jw)+frow*ta
+ enddo! gx
+ enddo! gy
+ enddo! gz
+ enddo! gw
+enddo; enddo; enddo; enddo! ix, iy, iz, iw
+a=b
+end subroutine rbeta4t
+
+
+!=============================================================================
+module subroutine vrbeta4t(this,nv,hx,lx,mx, hy,ly,my, hz,lz,mz, &
+ hw,lw,mw, el,ss, a) ! [rbetat]
+!=============================================================================
+! Vector version of rbeta4t filtering nv fields at once.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: nv, &
+ hx,Lx,mx,&
+ hy,ly,my,&
+ hz,lz,mz,&
+ hw,lw,mw
+real(dp),dimension(4,4,Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: ss
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy,&
+ lz-hz:mz+hz,lw-hw:mw+hw), intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy,&
+ lz-hz:mz+hz,lw-hw:mw+hw) :: b
+real(dp),dimension(nv) :: ta
+real(dp),dimension(4,4) :: tel
+real(dp):: s,rr,rrx,rry,rrz,rrc,frow,&
+ exx,eyy,ezz,eww,eyx,ezx,ewx,ezy,ewy,ewz,x,y,z,w,xc,yc,zc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+integer :: iz,jz,gz
+integer :: iw,jw,gw
+!=============================================================================
+b=0
+do iw=Lw,Mw; do iz=Lz,Mz; do iy=Ly,My; do ix=Lx,Mx
+ ta=a(:,ix,iy,iz,iw); s=ss(ix,iy,iz,iw)
+ tel=el(:,:,ix,iy,iz,iw)*this%rmom2_4
+ exx=tel(1,1); eyy=tel(2,2); ezz=tel(3,3); eww=tel(4,4)
+ eyx=tel(2,1); ezx=tel(3,1); ewx=tel(4,1)
+ ezy=tel(3,2); ewy=tel(4,2)
+ ewz=tel(4,3)
+ z=u1/ezz
+ do gw=ceiling(-w+eps),floor( w-eps)
+ jw=iw+gw; w=gw; zc=-w*ewz
+ rrz=(w*eww)**2; z =sqrt(u1-rrz)
+ do gz=ceiling((zc-z)/ezz+eps),floor((zc+z)/ezz-eps)
+ jz=iz+gz; z=gz; yc=-z*ezy-w*ewy
+ rry=rrz+(z*ezz-zc)**2; y =sqrt(u1-rry)
+ do gy=ceiling((yc-y)/eyy+eps),floor((yc+y)/eyy-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx-z*ezx-w*ewx
+ rrx=rry+(y*eyy-yc)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ b(:,jx,jy,jz,jw)=b(:,jx,jy,jz,jw)+frow*ta
+ enddo! gx
+ enddo! gy
+ enddo! gz
+ enddo! gw
+enddo; enddo; enddo; enddo! ix, iy, iz, iw
+a=b
+end subroutine vrbeta4t
+
+! Vector versions of the above routines:
+!=============================================================================
+module subroutine vrbeta1(this,nv,hx,lx,mx, el,ss, a) ! [rbeta]
+!=============================================================================
+! Vector version of rbeta1 filtering nv fields at once.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: nv,hx,Lx,mx
+real(dp),dimension(1,1, Lx:Mx), intent(in ):: el
+real(dp),dimension( Lx:Mx), intent(in ):: ss
+real(dp),dimension(nv,lx-hx:mx+hx),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(nv,lx-hx:mx+hx):: b
+real(dp),dimension(nv) :: tb
+real(dp) :: x,s,rr,rrc,frow,exx
+integer :: ix,jx,gx
+!=============================================================================
+b=0
+do ix=Lx,Mx
+ tb=0; s=ss(ix)
+ exx=el(1,1,ix)*this%rmom2_1
+ x=u1/exx
+ do gx=ceiling(-x+eps),floor( x-eps)
+ jx=ix+gx; x=gx
+ rr=(x*exx)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ tb=tb+frow*a(:,jx)
+ enddo
+ b(:,ix)=tb
+enddo
+a=b
+end subroutine vrbeta1
+
+!=============================================================================
+module subroutine vrbeta2(this,nv,hx,lx,mx, hy,ly,my, el,ss, a) ! [rbeta]
+!=============================================================================
+! Vector version of rbeta2 filtering nv fields at once.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: nv, &
+ hx,Lx,mx, &
+ hy,ly,my
+real(dp),dimension( 2,2,Lx:Mx,Ly:My), intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My), intent(in ):: ss
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy):: b
+real(dp),dimension(nv) :: tb
+real(dp),dimension(2,2) :: tel
+real(dp) :: s,rr,rrx,rrc,&
+ frow,exx,eyy,eyx,x,y,xc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+!=============================================================================
+b=0
+do iy=Ly,My; do ix=Lx,Mx
+ tb=0; s=ss(ix,iy)
+ tel=el(:,:,ix,iy)*this%rmom2_2 ! This el, rescaled
+ exx=tel(1,1); eyy=tel(2,2)
+ eyx=tel(2,1)
+ y=u1/eyy
+ do gy=ceiling(-y+eps),floor( y-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx
+ rrx=(y*eyy)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ tb=tb+frow*a(:,jx,jy)
+ enddo! gx
+ enddo! gy
+ b(:,ix,iy)=tb
+enddo; enddo! ix, iy
+a=b
+end subroutine vrbeta2
+
+!=============================================================================
+module subroutine vrbeta3(this,nv, hx,lx,mx, hy,ly,my, hz,lz,mz, el,ss,a) ! [rbeta]
+!=============================================================================
+! Vector version of rbeta3 filtering nv fields at once.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: nv, &
+ hx,Lx,mx,&
+ hy,ly,my,&
+ hz,lz,mz
+real(dp),dimension(3,3,Lx:Mx,Ly:My,Lz:Mz), intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz), intent(in ):: ss
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy,&
+ lz-hz:mz+hz),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy,lz-hz:mz+hz):: b
+real(dp),dimension(nv) :: tb
+real(dp),dimension(3,3) :: tel
+real(dp):: s,rr,rrx,rry,rrc,frow,&
+ exx,eyy,ezz,eyx,ezx,ezy,x,y,z,xc,yc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+integer :: iz,jz,gz
+!=============================================================================
+b=0
+do iz=Lz,Mz; do iy=Ly,My; do ix=Lx,Mx
+ tb=0; s=ss(ix,iy,iz)
+ tel=el(:,:,ix,iy,iz)*this%rmom2_3
+ exx=tel(1,1); eyy=tel(2,2); ezz=tel(3,3)
+ eyx=tel(2,1); ezx=tel(3,1); ezy=tel(3,2)
+ z=u1/ezz
+ do gz=ceiling(-z+eps),floor( z-eps)
+ jz=iz+gz; z=gz; yc=-z*ezy
+ rry=(z*ezz)**2; y =sqrt(u1-rry)
+ do gy=ceiling((yc-y)/eyy+eps),floor((yc+y)/eyy-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx-z*ezx
+ rrx=rry+(y*eyy-yc)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ tb=tb+frow*a(:,jx,jy,jz)
+ enddo! gx
+ enddo! gy
+ enddo! gz
+ b(:,ix,iy,iz)=tb
+enddo; enddo; enddo! ix, iy, iz
+a=b
+end subroutine vrbeta3
+
+! Vector versions of the above routines:
+!=============================================================================
+module subroutine vrbeta1T(this,nv, hx,lx,mx, el,ss, a) ! [rbetat]
+!=============================================================================
+! Vector version of rbeta1t filtering nv fields at once.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: nv,hx,Lx,mx
+real(dp),dimension(1,1,Lx:Mx), intent(in ):: el
+real(dp),dimension( Lx:Mx), intent(in ):: ss
+real(dp),dimension(nv,lx-hx:mx+hx),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(nv,lx-hx:mx+hx):: b
+real(dp),dimension(nv) :: ta
+real(dp) :: s,rr,rrc,frow,exx,x
+integer :: ix,jx,gx
+!=============================================================================
+b=0
+do ix=Lx,Mx
+ ta=a(:,ix); s=ss(ix)
+ exx=el(1,1,ix)*this%rmom2_1
+ x=u1/exx
+ do gx=ceiling(-x+eps),floor( x-eps)
+ jx=ix+gx; x=gx
+ rr=(x*exx)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ b(:,jx)=b(:,jx)+frow*ta
+ enddo
+enddo
+a=b
+end subroutine vrbeta1t
+!=============================================================================
+module subroutine vrbeta2T(this,nv,hx,lx,mx, hy,ly,my, el,ss, a) ! [rbetat]
+!=============================================================================
+! Vector version of rbeta2t filtering nv fields at once.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: nv, &
+ hx,Lx,mx, &
+ hy,ly,my
+real(dp),dimension( 2,2,Lx:Mx,Ly:My), intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My), intent(in ):: ss
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy):: b
+real(dp),dimension(nv) :: ta
+real(dp),dimension(2,2) :: tel
+real(dp) :: s,rr,rrx,rrc, &
+ frow,exx,eyy,eyx,x,y,xc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+!=============================================================================
+b=0
+do iy=Ly,My; do ix=Lx,Mx
+ ta=a(:,ix,iy); s=ss(ix,iy)
+ tel=el(:,:,ix,iy)*this%rmom2_2 ! This el, rescaled
+ exx=tel(1,1); eyy=tel(2,2)
+ eyx=tel(2,1)
+ y=u1/eyy
+ do gy=ceiling(-y+eps),floor( y-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx
+ rrx=(y*eyy)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ b(:,jx,jy)=b(:,jx,jy)+frow*ta
+ enddo! gx
+ enddo! gy
+enddo; enddo ! ix, iy
+a=b
+end subroutine vrbeta2t
+
+!=============================================================================
+module subroutine vrbeta3T(this,nv,hx,lx,mx, hy,ly,my, hz,lz,mz, el,ss, a) ! [rbetat]
+!=============================================================================
+! Vector version of rbeta3t filtering nv fields at once.
+!=============================================================================
+class(mg_parameter_type)::this
+integer, intent(in ):: nv, &
+ hx,Lx,mx,&
+ hy,ly,my,&
+ hz,lz,mz
+real(dp),dimension( 3,3,Lx:Mx,Ly:My,Lz:Mz),intent(in ):: el
+real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz),intent(in ):: ss
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy,&
+ lz-hz:mz+hz),intent(inout):: a
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-12
+real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy,&
+ lz-hz:mz+hz):: b
+real(dp),dimension(nv) :: ta
+real(dp),dimension(3,3) :: tel
+real(dp):: s,rr,rrx,rry,rrc,frow,&
+ exx,eyy,ezz,eyx,ezx,ezy,x,y,z,xc,yc
+integer :: ix,jx,gx
+integer :: iy,jy,gy
+integer :: iz,jz,gz
+!=============================================================================
+b=0
+do iz=Lz,Mz; do iy=Ly,My; do ix=Lx,Mx
+ ta=a(:,ix,iy,iz); s=ss(ix,iy,iz)
+ tel=el(:,:,ix,iy,iz)*this%rmom2_3
+ exx=tel(1,1); eyy=tel(2,2); ezz=tel(3,3)
+ eyx=tel(2,1); ezx=tel(3,1); ezy=tel(3,2)
+ z=u1/ezz
+ do gz=ceiling(-z+eps),floor( z-eps)
+ jz=iz+gz; z=gz; yc=-z*ezy
+ rry=(z*ezz)**2; y =sqrt(u1-rry)
+ do gy=ceiling((yc-y)/eyy+eps),floor((yc+y)/eyy-eps)
+ jy=iy+gy; y=gy; xc=-y*eyx-z*ezx
+ rrx=rry+(y*eyy-yc)**2; x =sqrt(u1-rrx)
+ do gx=ceiling((xc-x)/exx+eps),floor((xc+x)/exx-eps)
+ jx=ix+gx; x=gx
+ rr=rrx+(x*exx-xc)**2; rrc=u1-rr
+ frow=s*rrc**this%p
+ b(:,jx,jy,jz)=b(:,jx,jy,jz)+frow*ta
+ enddo! gx
+ enddo! gy
+ enddo! gz
+enddo; enddo; enddo! ix, iy, iz
+a=b
+end subroutine vrbeta3t
+
+end submodule jp_pbfil
+
diff --git a/src/mgbf/jp_pbfil2.f90 b/src/mgbf/jp_pbfil2.f90
new file mode 100644
index 0000000000..63493f9727
--- /dev/null
+++ b/src/mgbf/jp_pbfil2.f90
@@ -0,0 +1,1173 @@
+module jp_pbfil2
+!$$$ module documentation block
+! . . . .
+! module: jp_pbfil2
+! prgmmr: purser org: NOAA/EMC date: 2019-08
+!
+! abstract: Module of data defining the exact transition rules
+! of the decad algorithm based on the PG(3,2) reference
+! geometry
+!
+! module history log:
+!
+! Subroutines Included:
+!
+! Functions Included:
+!
+! remarks:
+! An overview of this topic is given NOAA/NCEP Office Note 500.
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+use jp_pkind, only: spi,dp
+implicit none
+public
+private :: X, A, B
+integer(spi),parameter :: X=99,A=10,B=11
+!---- Items that relate to beta line filters generally:
+real(dp),allocatable,dimension(:) :: bnorm,bsprds
+integer(spi) :: p,nh
+!---- Items that relate only to 4D "decad" line filters:
+integer(spi),dimension(4,0:9) :: dec0,dodec0t
+integer(spi),dimension(4,0:11) :: dodec0
+integer(spi),dimension(0:14,0:14) :: typ
+integer(spi),dimension(0:3,0:3,0:9,0:11) :: umat10
+integer(spi),dimension(0:3,0:3,0:3,12:59):: umat12
+integer(spi),dimension(0:3,0:3,4:9) :: umats
+integer(spi),dimension(0:9,0:59) :: nei
+integer(spi),dimension(0:9,0:11) :: dcol10
+integer(spi),dimension(0:3,12:59) :: dcol12
+integer(spi),dimension(2, 0:3) :: nei0a,jcora
+integer(spi),dimension(2,1:2,4:9) :: nei0b,jcorb
+integer(spi),dimension(2) :: nei17,nei22,nei33,nei38
+integer(spi),dimension(4,4,0:12) :: tcors
+integer(spi),dimension(0:2,0:3) :: kcor10a5
+integer(spi),dimension(0:2,4:9) :: kcor10b1,kcor10b2
+integer(spi),dimension(12:59) :: kcor12b0
+integer(spi),dimension(0:2) :: kcor17c0,kcor22c0,kcor33c0,kcor38c0, &
+ kcor44c0,kcor51c0,kcor53c0,kcor58c0
+integer(spi),dimension(0:9,0:2) :: twt10a5,twt10b1,twt10b2,twt12c0
+integer(spi),dimension(0:9,0:9) :: qwt10a,qwt10b,qwt10c,qwt10d,qwt10e, &
+ qwt12a,qwt12b
+integer(spi),dimension(0:9,0:2) :: qwt12b0
+integer(spi),dimension(0:9,0:12) :: tperms
+integer(spi),dimension(0:9,0:9,0:11) :: perm10
+integer(spi),dimension(0:9,0:3,12:59) :: perm12
+integer(spi),dimension(0:9,4:9) :: perms
+data p/0/
+data nh/0/
+data dec0/1,0,0,0, 0,1, 0,0, 0, 0,1, 0, 0,0,0,1, -1,-1,-1,-1, &
+ 1,0,1,1, -1,0,-1,0, 0,-1,0,-1, 1,1,0,1, -1, 0, 0,-1/
+data dodec0t/ &
+ +2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, &
+ -1,-1,-1,-1, 1, 1,-1,-1, 1,-1, 1,-1, &
+ -1, 1, 1, 1, -1, 1,-1,-1, -1,-1, 1,-1 /
+data dodec0/ &
+ +2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, &
+ -1,-1,-1,-1, 1, 1,-1,-1, 1,-1, 1,-1, 1,-1,-1, 1, &
+ -1, 1, 1, 1, -1, 1,-1,-1, -1,-1, 1,-1, -1,-1,-1, 1/
+data typ/ X,6,8,X,X,X,X,7,3,9,5,1,0,2,4, &! 3;1;1;1;9
+ X,3,6,9,8,5,X,1,X,0,X,2,X,4,7, &! 6;2;2;2;3
+ X,X,3,0,6,X,9,2,8,X,5,4,X,7,1, &! 1;4;4;3;3
+ X,8,X,X,3,5,0,4,6,X,X,7,9,1,2, &! 2;1;6;1;5
+!---------
+ X,X,X,8,6,4,X,X,7,3,9,2,1,0,5, &! 1;1;4;1;8
+ X,7,X,3,X,9,8,2,6,1,4,0,X,5,X, &! 2;2;8;2;1
+ X,6,7,1,X,4,3,0,X,X,9,5,8,X,2, &! 4;4;1;4;2
+ X,X,6,X,7,9,1,5,X,8,4,X,3,2,0, &! 1;2;5;3;4
+!---------
+ 9,X,0,5,X,4,X,7,3,X,X,1,8,6,2, &! 3;2;3;1;6
+ 9,3,X,X,0,X,5,1,X,8,4,6,X,2,7, &! 1;2;3;4;5
+!---------
+ X,1,5,9,6,4,2,X,7,8,3,X,0,X,X, &! 4;2;1;1;7
+!---------
+ X,7,0,X,9,8,X,4,1,X,3,5,X,2,6, &! 3;3;3;3;3
+!+++++++++
+ X,1,X,4,2,3,5,B,X,A,0,9,8,7,6, &! 2;6;7
+ X,X,1,A,X,0,4,9,2,8,3,7,5,6,B, &! 1;3;11
+!---------
+ X,0,3,B,2,X,4,7,1,5,X,8,9,6,A/ ! 5;5;5
+data umat10/&
+!---------------- 0
+ 1, 1, 1, 1, 0, 1,-1, 1, 0, 0, 0, 1, -1, 0, 0,-1, &
+ 0, 0, 1, 0, -2,-1,-1,-2, 0,-1, 0,-1, 0, 0, 0, 1, &
+ 0, 0, 0, 1, -1,-1,-1,-1, -1,-1, 0,-1, 2, 0, 1, 1, &
+ 1, 1, 1, 1, 1, 0, 0, 0, 1,-1, 1, 0, -1, 0, 0,-1, &
+ 1, 0, 0, 1, 0,-1, 0,-1, 1, 0, 1, 0, 0, 1,-1, 0, &
+ 1, 1, 0, 1, 0,-1,-1, 0, 0, 0, 0, 1, 1, 0, 1, 0, &
+ 1, 1, 0, 1, 0,-1,-1,-1, -1, 0,-1,-1, 0, 0, 0, 1, &
+ 0, 0, 1, 0, 0, 1, 0, 0, 2, 1, 1, 1, 0, 0, 0, 1, &
+ 1, 0, 1, 1, -1, 0, 0, 0, 0, 1, 0, 1, 0,-1,-1, 0, &
+ 0, 1, 0, 1, -1, 0,-1,-1, 1, 1, 0, 0, 0, 0, 1, 0, &
+!---------------- 1
+ 1, 1, 1, 1, 0, 1,-1, 1, 0, 0, 0, 1, -1, 0, 0,-1, &
+ 0, 0, 1, 0, -2,-1,-1,-2, 0,-1, 0,-1, 0, 0, 0, 1, &
+ 0, 0, 0, 1, -1,-1,-1,-1, -1,-1, 0,-1, 2, 0, 1, 1, &
+ 1, 1, 1, 1, -1, 1,-1, 0, -1, 0, 0, 0, 1, 0, 0, 1, &
+ 1, 0, 0, 1, -1, 0,-1, 0, 0, 1, 0, 1, 0,-1, 1, 0, &
+ 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0,-1, 0,-1,-1, 0, &
+ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0,-1, &
+ 0, 0, 1, 0, -2,-1,-1,-1, 0,-1, 0, 0, 0, 0, 0,-1, &
+ 1, 0, 1, 1, 0,-1, 0,-1, 1, 0, 0, 0, 0, 1, 1, 0, &
+ 0, 1, 0, 1, -1,-1, 0, 0, 1, 0, 1, 1, 0, 0,-1, 0, &
+!---------------- 2
+ 1, 1, 1, 1, 0, 0, 0,-1, 0,-1, 1,-1, 1, 0, 0, 1, &
+ 0, 0, 1, 0, 0, 1, 0, 1, 2, 1, 1, 2, 0, 0, 0,-1, &
+ 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, -2, 0,-1,-1, &
+ 1, 1, 1, 1, -1, 1,-1, 0, -1, 0, 0, 0, 1, 0, 0, 1, &
+ 1, 0, 0, 1, -1, 0,-1, 0, 0, 1, 0, 1, 0,-1, 1, 0, &
+ 1, 1, 0, 1, 0,-1,-1, 0, 0, 0, 0, 1, 1, 0, 1, 0, &
+ 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0,-1, &
+ 0, 0, 1, 0, -2,-1,-1,-1, 0,-1, 0, 0, 0, 0, 0,-1, &
+ 1, 0, 1, 1, 0,-1, 0,-1, 1, 0, 0, 0, 0, 1, 1, 0, &
+ 0, 1, 0, 1, -1,-1, 0, 0, 1, 0, 1, 1, 0, 0,-1, 0, &
+ !---------------- 3
+ 1, 1, 1, 1, 0, 0, 0,-1, 0,-1, 1,-1, 1, 0, 0, 1, &
+ 0, 0, 1, 0, 0, 1, 0, 1, 2, 1, 1, 2, 0, 0, 0,-1, &
+ 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, -2, 0,-1,-1, &
+ 1, 1, 1, 1, 1, 0, 0, 0, 1,-1, 1, 0, -1, 0, 0,-1, &
+ 1, 0, 0, 1, 0,-1, 0,-1, 1, 0, 1, 0, 0, 1,-1, 0, &
+ 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0,-1, 0,-1,-1, 0, &
+ 1, 1, 0, 1, 0,-1,-1,-1, -1, 0,-1,-1, 0, 0, 0, 1, &
+ 0, 0, 1, 0, 0, 1, 0, 0, 2, 1, 1, 1, 0, 0, 0, 1, &
+ 1, 0, 1, 1, -1, 0, 0, 0, 0, 1, 0, 1, 0,-1,-1, 0, &
+ 0, 1, 0, 1, -1, 0,-1,-1, 1, 1, 0, 0, 0, 0, 1, 0, &
+!---------------- 4
+ 1, 0, 1, 1, 0,-1, 0,-1, -1,-1, 0,-1, 0, 0,-1, 1, &
+ 1, 0, 1, 0, -1,-1,-1,-2, -1, 0, 0,-1, 1, 1, 0, 1, &
+ 0, 0, 0, 1, 2, 0, 1, 1, 1, 1, 0, 1, -1,-1,-1,-1, &
+ 0, 0, 1, 0, 0, 1, 0, 0, -2, 0,-1,-1, 0,-1, 0,-1, &
+ 0, 0, 0, 1, 0, 0, 1, 0, 1,-1, 1, 0, 1, 1, 0, 1, &
+ 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0,-1, 0,-1,-1, 0, &
+ 1, 0, 0, 1, 0,-1, 0,-1, 0, 0,-1,-1, 1, 1, 1, 1, &
+ 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, -1,-1,-1,-1, &
+ 1, 0, 1, 0, 0,-1,-1,-1, 0,-1, 0, 0, -1, 0, 0,-1, &
+ 0, 1, 0, 1, 0, 0,-1, 0, 1, 1, 0, 0, 1, 0, 1, 1, &
+!---------------- 5
+ 1, 0, 1, 1, 0,-1, 0,-1, -1,-1, 0,-1, 0, 0,-1, 1, &
+ 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, -1,-1,-1,-2, &
+ 0, 0, 0, 1, -1,-1,-1,-1, -1,-1, 0,-1, 2, 0, 1, 1, &
+ 0, 0, 1, 0, 0, 1, 0, 0, -2, 0,-1,-1, 0,-1, 0,-1, &
+ 0, 0, 0, 1, -1, 1,-1, 0, 0, 0,-1, 0, -1,-1, 0,-1, &
+ 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0,-1, 0,-1,-1, 0, &
+ 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, -1,-1,-1,-1, &
+ 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, -1,-1,-1,-1, &
+ 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, &
+ 0, 1, 0, 1, -1,-1, 0, 0, 0, 0, 1, 0, -1, 0,-1,-1, &
+!---------------- 6
+ 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1,-1, &
+ 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 2, -1, 0,-1,-1, &
+ 0, 0, 0, 1, 2, 0, 1, 1, 1, 1, 0, 1, -1,-1,-1,-1, &
+ 0, 0, 1, 0, 2, 0, 1, 1, 0,-1, 0, 0, 0, 1, 0, 1, &
+ 0, 0, 0, 1, -1, 1,-1, 0, 0, 0,-1, 0, -1,-1, 0,-1, &
+ 1, 1, 0, 1, 0, 0, 0, 1, -1, 0,-1, 0, 0, 1, 1, 0, &
+ 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, -1,-1,-1,-1, &
+ 1, 0, 0, 1, -1, 0,-1, 0, -1,-1, 0, 0, 1, 1, 1, 1, &
+ 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, &
+ 0, 1, 0, 1, -1,-1, 0, 0, 0, 0, 1, 0, -1, 0,-1,-1, &
+!---------------- 7
+ 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1,-1, &
+ 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, -1,-1,-1,-2, &
+ 0, 1, 0, 1, 2, 1, 1, 1, 1, 0, 1, 1, -1, 0, 0,-1, &
+ 0, 0, 1, 0, 2, 0, 1, 1, 0,-1, 0, 0, 0, 1, 0, 1, &
+ 0, 0, 0, 1, 0, 0, 1, 0, 1,-1, 1, 0, 1, 1, 0, 1, &
+ 1, 1, 0, 1, 0, 0, 0, 1, -1, 0,-1, 0, 0, 1, 1, 0, &
+ 1, 0, 0, 1, 0,-1, 0,-1, 0, 0,-1,-1, 1, 1, 1, 1, &
+ 1, 0, 0, 1, -1, 0,-1, 0, -1,-1, 0, 0, 1, 1, 1, 1, &
+ 1, 0, 1, 0, 0,-1,-1,-1, 0,-1, 0, 0, -1, 0, 0,-1, &
+ 0, 1, 0, 1, 0, 0,-1, 0, 1, 1, 0, 0, 1, 0, 1, 1, &
+!---------------- 8
+ 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1,-1, &
+ 1, 0, 0, 0, -1,-1, 0,-2, -1,-1,-1,-1, 1, 0, 1, 1, &
+ 0, 0, 0, 1, -2, 0,-1,-1, -1,-1,-1,-1, 1, 1, 0, 1, &
+ 1, 1, 0, 1, -1, 0,-1, 0, -1, 0,-1,-1, 1,-1, 0, 0, &
+ 1, 0, 0, 1, 1, 0, 1, 0, 0,-1, 0,-1, 0, 1,-1, 0, &
+ 1, 0, 0, 0, 0,-1, 0, 0, 0, 0,-1, 1, 1, 1, 1, 1, &
+ 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 2, 1, 0, 0, 0, &
+ 0, 0, 1, 0, -2,-1,-1,-1, 0,-1, 0, 0, 0, 0, 0,-1, &
+ 0, 0, 0, 1, -1, 1, 0, 0, 0, 0, 1, 0, -1,-1,-1,-1, &
+ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,-1, 0,-1, 1, 0, &
+!---------------- 9
+ 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1,-1, &
+ 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, -1,-1, 0,-2, &
+ 0, 1, 0, 0, 2, 1, 1, 2, 1, 0, 0, 0, -1, 0,-1, 0, &
+ 1, 1, 0, 1, -1, 0,-1, 0, -1, 0,-1,-1, 1,-1, 0, 0, &
+ 1, 0, 0, 1, 0, 1, 0, 1, -1, 0,-1, 0, 0,-1, 1, 0, &
+ 1, 0, 0, 0, 0,-1, 0, 0, 0, 0,-1, 1, 1, 1, 1, 1, &
+ 0, 1, 0, 0, -1,-1,-1,-2, 0, 0,-1, 0, -1, 0, 0, 0, &
+ 0, 0, 1, 0, 0, 1, 0, 0, 2, 1, 1, 1, 0, 0, 0, 1, &
+ 0, 0, 0, 1, -1, 1, 0, 0, 0, 0, 1, 0, -1,-1,-1,-1, &
+ 1, 1, 1, 1, 0, 0, 0, 1, -1, 0, 0, 0, 0, 1,-1, 0, &
+!---------------- 10
+ 0, 1, 0, 0, 1, 1, 0, 2, -1, 0,-1, 0, 0, 0, 1, 0, &
+ 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 2, -1,-1, 0,-1, &
+ 0, 1, 0, 1, -2,-1,-1,-1, -1, 0,-1,-1, 1, 0, 0, 1, &
+ 1, 1, 1, 1, -1, 0, 0,-1, -1, 0, 0, 0, 1,-1, 1, 0, &
+ 0, 0, 0, 1, 1, 1, 0, 1, 0, 0,-1, 0, 1,-1, 1, 0, &
+ 0, 1, 0, 1, 0, 0,-1, 0, -1,-1,-1, 0, -1, 0, 0,-1, &
+ 0, 1, 0, 0, -1,-1,-1,-2, 1, 0, 0, 0, 0, 0, 1, 0, &
+ 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, -1, 0, 0, 0, &
+ 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, &
+ 1, 0, 1, 0, 0, 1, 0, 0, 0, 0,-1,-1, -1,-1, 0,-1, &
+!---------------- 11
+ 1, 1, 1, 1, -1, 0, 0,-1, 0, 0, 0,-1, 0, 1,-1, 1, &
+ 0, 0, 1, 0, 0, 0, 0,-1, 0,-1, 0,-1, 2, 1, 1, 2, &
+ 0, 1, 0, 0, -1, 0,-1, 0, -1, 0, 0, 0, 2, 1, 1, 2, &
+ 1, 1, 0, 1, -1, 0,-1,-1, -1, 0,-1, 0, 1,-1, 0, 0, &
+ 1, 0, 0, 0, 0, 1, 0, 0, -1, 0,-1,-1, 0,-1, 1,-1, &
+ 0, 1, 0, 1, 0, 0, 1, 0, -1, 0, 0,-1, -1,-1,-1, 0, &
+ 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0,-1,-1, &
+ 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, -1,-1,-1, 0, &
+ 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1,-1, 0, 0, &
+ 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1/
+data umat12/&
+!---------------- 12
+ 0, 2,-2, 0, 1, 1, 1, 1, -1, 1, 1, 1, 0, 0, 0,-2, &
+ 1, 1,-1, 1, 0, 0, 2, 2, -2, 0, 0, 0, 0, 0, 0,-2, &
+ 1, 1,-1,-1, 0,-2, 0,-2, -2, 0, 0, 0, 0, 0, 0, 2, &
+ 0, 0, 2, 0, -1, 1,-1,-1, -1, 1,-1, 1, 0,-2, 0, 0, &
+!---------------- 13
+ 0, 0, 2, 2, -1,-1, 1,-1, 1,-1, 1,-1, 0, 2, 0, 0, &
+ 1, 1, 1, 1, 1,-1, 1, 1, 0, 0,-2, 0, -2, 0, 0, 0, &
+ 1, 1,-1, 1, 1,-1, 1, 1, -1, 1, 1, 1, 0, 0, 0,-2, &
+ 0, 2,-2, 0, -1, 1, 1, 1, 1,-1, 1, 1, 1,-1, 1,-1, &
+!---------------- 14
+ 0, 2, 0, 2, 0, 0, 2, 0, -1,-1, 1, 1, -1, 1,-1,-1, &
+ 1,-1,-1,-1, -1,-1, 1,-1, -1, 1,-1,-1, 1, 1, 1, 1, &
+ 1, 1,-1,-1, 0,-2, 0,-2, 1,-1, 1, 1, -1, 1, 1, 1, &
+ 1,-1,-1,-1, -1,-1, 1,-1, -1,-1, 1, 1, 1, 1, 1, 1, &
+!---------------- 15
+ 0, 2, 0, 2, 1, 1,-1,-1, 0, 0,-2, 0, 1,-1, 1, 1, &
+ 1, 1,-1, 1, 1,-1, 1, 1, 0, 0, 2, 0, -2, 0, 0, 0, &
+ 1,-1,-1,-1, -1, 1,-1, 1, 0, 2, 0, 0, -1,-1, 1,-1, &
+ 1,-1,-1,-1, 1,-1, 1, 1, -1, 1,-1, 1, 0, 2, 0, 0, &
+!---------------- 16
+ 0, 0, 2, 2, -1,-1, 1,-1, 0,-2, 0, 0, -1, 1,-1, 1, &
+ 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 2, -1,-1,-1,-1, &
+ 1, 1, 1, 1, -1,-1, 1, 1, -1, 1,-1, 1, 1,-1,-1,-1, &
+ 1, 1, 1, 1, -1,-1, 1, 1, -1,-1, 1,-1, 1,-1,-1,-1, &
+!---------------- 17
+ 0, 2, 0, 2, -1, 1,-1,-1, 0, 0,-2, 0, -1,-1, 1, 1, &
+ 1,-1, 1, 1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 0,-2,-2, &
+ 1, 1,-1, 1, 0,-2, 0, 0, -2, 0, 0, 0, 0, 0, 0,-2, &
+ 0, 0, 2, 0, -1,-1, 1, 1, 1, 1,-1, 1, 1,-1,-1,-1, &
+ !---------------- 18
+ 0, 2,-2, 0, -1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,-2, &
+ 0, 0, 2, 2, -1,-1, 1,-1, -1, 1,-1,-1, 0, 0,-2, 0, &
+ 0, 2, 0, 2, 1, 1,-1,-1, 1,-1, 1,-1, 0,-2, 0, 0, &
+ 0, 0, 2, 0, -2, 0, 0, 0, 0, 2,-2, 0, 1,-1,-1,-1, &
+!---------------- 19
+ 0, 2,-2, 0, 0, 0, 0,-2, -1,-1,-1,-1, -1, 1, 1, 1, &
+ 1, 1,-1,-1, -1, 1, 1, 1, 0, 0, 0, 2, -1,-1,-1,-1, &
+ 1, 1,-1, 1, 0, 2, 0, 0, 1,-1, 1,-1, -1,-1, 1, 1, &
+ 1,-1, 1, 1, 1,-1, 1,-1, -1,-1,-1,-1, 0, 2,-2, 0, &
+!---------------- 20
+ 0, 2, 0, 2, 1,-1, 1, 1, -1,-1, 1, 1, 0, 0,-2, 0, &
+ 1, 1,-1,-1, 1,-1, 1,-1, -1,-1,-1,-1, 0, 0, 0, 2, &
+ 2, 0, 0, 0, 0,-2, 0, 0, -1, 1,-1, 1, -1, 1, 1, 1, &
+ 0, 2,-2, 0, -1,-1,-1,-1, 1,-1, 1,-1, 1,-1, 1, 1, &
+!---------------- 21
+ 0, 2,-2, 0, -1,-1,-1,-1, 1,-1,-1,-1, 0, 0, 0, 2, &
+ 1, 1,-1,-1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 0, 0, 2, &
+ 1, 1,-1, 1, 0,-2, 0, 0, -2, 0, 0, 0, 0, 0, 0,-2, &
+ 1,-1,-1,-1, 1,-1, 1, 1, 0, 0, 2, 0, -2, 0, 0, 0, &
+!---------------- 22
+ 0, 0, 2, 2, 1,-1, 1,-1, 0,-2, 0, 0, 1, 1,-1, 1, &
+ 0, 0, 0, 2, -2, 0, 0, 0, 0, 0, 2, 0, 1, 1,-1,-1, &
+ 1,-1, 1,-1, 0,-2, 0, 0, -2, 0, 0, 0, 0, 2, 0, 2, &
+ 0, 2, 0, 0, 1, 1,-1, 1, -1,-1, 1, 1, -1,-1,-1,-1, &
+!---------------- 23
+ 0, 2, 0, 2, 0, 0, 2, 0, -1,-1, 1, 1, -1, 1,-1,-1, &
+ 1, 1,-1,-1, -1, 1,-1, 1, 0, 0, 2, 2, -1,-1, 1,-1, &
+ 1,-1,-1,-1, -1, 1,-1, 1, -1,-1, 1, 1, 1, 1, 1, 1, &
+ 1,-1, 1, 1, 1,-1,-1,-1, 0, 2,-2, 0, -2, 0, 0, 0, &
+!---------------- 24
+ 0, 0, 2, 2, 0, 2, 0, 0, 1, 1,-1, 1, 1,-1, 1,-1, &
+ 1, 1, 1, 1, -1, 1,-1,-1, 0, 0,-2, 0, -1,-1, 1, 1, &
+ 1, 1,-1,-1, 1,-1, 1,-1, 0,-2, 0, 0, -2, 0, 0, 0, &
+ 1, 1, 1, 1, 1,-1, 1,-1, -1, 1,-1,-1, 0, 0,-2, 0, &
+!---------------- 25
+ 0, 0, 2, 2, -1,-1, 1,-1, 0,-2, 0, 0, -1, 1,-1, 1, &
+ 1, 1, 1, 1, -1, 1,-1,-1, -1,-1, 1,-1, 1,-1,-1,-1, &
+ 0, 0, 0, 2, -1, 1, 1, 1, 1,-1, 1,-1, 1, 1,-1,-1, &
+ 1,-1, 1,-1, 1, 1, 1, 1, 0, 2,-2, 0, -2, 0, 0, 0, &
+!---------------- 26
+ 0, 2,-2, 0, 1,-1,-1,-1, 0, 0, 0,-2, 1, 1, 1, 1, &
+ 1, 1,-1,-1, 0, 0,-2, 0, 1,-1, 1, 1, -1,-1, 1,-1, &
+ 1, 1,-1, 1, -1,-1,-1,-1, 0, 0, 0,-2, -1, 1, 1, 1, &
+ 0, 2,-2, 0, -1, 1, 1, 1, 1,-1, 1, 1, 1,-1, 1,-1, &
+!---------------- 27
+ 0, 2,-2, 0, 1, 1, 1, 1, -1, 1, 1, 1, 0, 0, 0,-2, &
+ 0, 0, 2, 0, -1,-1, 1, 1, -1, 1,-1, 1, 0, 0,-2,-2, &
+ 0, 2, 0, 0, 1, 1,-1, 1, 1,-1, 1, 1, 0,-2, 0,-2, &
+ 1,-1,-1,-1, -1, 1,-1,-1, -1, 1,-1, 1, 1, 1, 1, 1, &
+!---------------- 28
+ 0, 2,-2, 0, 1, 1, 1, 1, -1, 1, 1, 1, 0, 0, 0,-2, &
+ 1, 1,-1, 1, 0, 0, 2, 2, -2, 0, 0, 0, 0, 0, 0,-2, &
+ 1, 1,-1,-1, 0,-2, 0,-2, -2, 0, 0, 0, 0, 0, 0, 2, &
+ 0, 2, 0, 0, 1,-1, 1,-1, 1,-1, 1, 1, 0, 0,-2, 0, &
+!---------------- 29
+ 0, 0, 2, 2, -1,-1, 1,-1, 1,-1, 1,-1, 0, 2, 0, 0, &
+ 1, 1, 1, 1, 1,-1, 1, 1, 0, 0,-2, 0, -2, 0, 0, 0, &
+ 1, 1,-1, 1, 1,-1, 1, 1, -1, 1, 1, 1, 0, 0, 0,-2, &
+ 0, 2,-2, 0, -1, 1, 1, 1, 1,-1, 1, 1, 1,-1, 1,-1, &
+!---------------- 30
+ 0, 2, 0, 2, 0, 0, 2, 0, -1,-1, 1, 1, -1, 1,-1,-1, &
+ 1,-1,-1,-1, -1,-1, 1,-1, -1, 1,-1,-1, 1, 1, 1, 1, &
+ 1,-1, 1, 1, -1,-1, 1,-1, 0, 2, 0, 0, -1, 1,-1, 1, &
+ 1,-1,-1,-1, -1,-1, 1,-1, -1,-1, 1, 1, 1, 1, 1, 1, &
+!---------------- 31
+ 0, 2, 0, 2, 0, 0, 2, 0, -1,-1, 1, 1, -1, 1,-1,-1, &
+ 1, 1,-1, 1, 1,-1, 1, 1, 0, 0, 2, 0, -2, 0, 0, 0, &
+ 1,-1,-1,-1, -1, 1,-1, 1, 0, 2, 0, 0, -1,-1, 1,-1, &
+ 1,-1,-1,-1, 1,-1, 1, 1, -1, 1,-1, 1, 0, 2, 0, 0, &
+!---------------- 32
+ 0, 0, 2, 2, -1,-1, 1,-1, 0,-2, 0, 0, -1, 1,-1, 1, &
+ 0, 0, 0, 2, 1,-1,-1,-1, -1,-1, 1,-1, -1, 1,-1,-1, &
+ 1, 1, 1, 1, -1,-1, 1, 1, -1, 1,-1, 1, 1,-1,-1,-1, &
+ 1, 1, 1, 1, -1,-1, 1, 1, -1,-1, 1,-1, 1,-1,-1,-1, &
+!---------------- 33
+ 0, 2, 0, 2, -1,-1, 1, 1, 0, 0, 2, 0, -1, 1,-1,-1, &
+ 1,-1, 1, 1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 0,-2,-2, &
+ 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, -1,-1, 1,-1, &
+ 0, 0, 2, 0, -1,-1, 1, 1, 1, 1,-1, 1, 1,-1,-1,-1, &
+!---------------- 34
+ 0, 2,-2, 0, -1,-1,-1,-1, 1,-1,-1,-1, 0, 0, 0, 2, &
+ 0, 0, 2, 2, -1,-1, 1,-1, -1, 1,-1,-1, 0, 0,-2, 0, &
+ 0, 2, 0, 2, 1, 1,-1,-1, 1,-1, 1,-1, 0,-2, 0, 0, &
+ 1,-1, 1, 1, -1, 1, 1, 1, -1,-1, 1,-1, 1, 1,-1,-1, &
+!---------------- 35
+ 0, 2,-2, 0, 0, 0, 0,-2, -1,-1,-1,-1, -1, 1, 1, 1, &
+ 1, 1,-1,-1, -1, 1, 1, 1, 0, 0, 0, 2, -1,-1,-1,-1, &
+ 1, 1,-1, 1, 0, 2, 0, 0, 1,-1, 1,-1, -1,-1, 1, 1, &
+ 1,-1, 1, 1, 1,-1, 1,-1, -1,-1,-1,-1, 0, 2,-2, 0, &
+!---------------- 36
+ 0, 2, 0, 2, 1,-1, 1, 1, -1,-1, 1, 1, 0, 0,-2, 0, &
+ 1, 1,-1,-1, 1,-1, 1,-1, -1,-1,-1,-1, 0, 0, 0, 2, &
+ 2, 0, 0, 0, 0,-2, 0, 0, -1, 1,-1, 1, -1, 1, 1, 1, &
+ 0, 2,-2, 0, -1,-1,-1,-1, 1,-1, 1,-1, 1,-1, 1, 1, &
+!---------------- 37
+ 0, 2,-2, 0, -1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,-2, &
+ 1, 1,-1,-1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 0, 0, 2, &
+ 1, 1,-1, 1, 0,-2, 0, 0, -2, 0, 0, 0, 0, 0, 0,-2, &
+ 0, 0, 2, 0, -1,-1, 1, 1, -1,-1,-1,-1, 0, 2,-2, 0, &
+!---------------- 38
+ 0, 2, 0, 2, 1, 1,-1,-1, -1, 1,-1,-1, 0, 0, 2, 0, &
+ 1, 1,-1,-1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 0, 0, 2, &
+ 1,-1, 1,-1, 0,-2, 0, 0, -2, 0, 0, 0, 0, 2, 0, 2, &
+ 0, 2, 0, 0, 1, 1,-1, 1, -1,-1, 1, 1, -1,-1,-1,-1, &
+!---------------- 39
+ 0, 2, 0, 2, 1, 1,-1,-1, 0, 0,-2, 0, 1,-1, 1, 1, &
+ 0, 0, 2, 2, -2, 0, 0, 0, 0, 0, 0,-2, 1,-1,-1,-1, &
+ 1,-1,-1,-1, -1, 1,-1, 1, -1,-1, 1, 1, 1, 1, 1, 1, &
+ 1,-1, 1, 1, 1,-1,-1,-1, 0, 2,-2, 0, -2, 0, 0, 0, &
+!---------------- 40
+ 0, 0, 2, 2, -1,-1, 1,-1, 0,-2, 0, 0, -1, 1,-1, 1, &
+ 1, 1, 1, 1, -1, 1,-1,-1, 0, 0,-2, 0, -1,-1, 1, 1, &
+ 1, 1,-1,-1, 1,-1, 1,-1, 0,-2, 0, 0, -2, 0, 0, 0, &
+ 1, 1, 1, 1, 1,-1, 1,-1, -1, 1,-1,-1, 0, 0,-2, 0, &
+!---------------- 41
+ 0, 0, 2, 2, 0, 2, 0, 0, 1, 1,-1, 1, 1,-1, 1,-1, &
+ 1, 1, 1, 1, -1, 1,-1,-1, -1,-1, 1,-1, 1,-1,-1,-1, &
+ 1,-1, 1,-1, 0, 2, 0, 0, 1, 1,-1, 1, -1,-1,-1,-1, &
+ 1,-1, 1,-1, 1, 1, 1, 1, 0, 2,-2, 0, -2, 0, 0, 0, &
+!---------------- 42
+ 0, 2,-2, 0, 1,-1,-1,-1, 0, 0, 0,-2, 1, 1, 1, 1, &
+ 1, 1,-1,-1, 0, 0,-2, 0, 1,-1, 1, 1, -1,-1, 1,-1, &
+ 1, 1,-1, 1, -1,-1,-1,-1, 0, 0, 0,-2, -1, 1, 1, 1, &
+ 0, 2,-2, 0, -1, 1, 1, 1, 1,-1, 1, 1, 1,-1, 1,-1, &
+ !---------------- 43
+ 0, 2,-2, 0, 1, 1, 1, 1, -1, 1, 1, 1, 0, 0, 0,-2, &
+ 0, 0, 2, 0, -1,-1, 1, 1, -1, 1,-1, 1, 0, 0,-2,-2, &
+ 0, 2, 0, 0, 1, 1,-1, 1, 1,-1, 1, 1, 0,-2, 0,-2, &
+ 1, 1, 1, 1, -1, 1,-1, 1, -1, 1,-1,-1, 1,-1,-1,-1, &
+!---------------- 44
+ 0, 2,-2, 0, -1, 1, 1, 1, 0, 0, 0, 2, -1,-1,-1,-1, &
+ 1,-1, 1,-1, 0, 0, 2, 2, -2, 0, 0, 0, 0, 0,-2, 0, &
+ 0, 0, 0, 2, -2, 0, 0, 0, 0,-2, 0,-2, 1, 1,-1,-1, &
+ 1, 1, 1, 1, 0, 2,-2, 0, -2, 0, 0, 0, 0,-2, 0, 0, &
+!---------------- 45
+ 0, 0, 2, 2, 0,-2, 0, 0, -1,-1, 1,-1, -1, 1,-1, 1, &
+ 1,-1,-1,-1, 1, 1,-1, 1, 0, 0, 2, 2, -2, 0, 0, 0, &
+ 2, 0, 0, 0, 0, 0, 0,-2, -1, 1, 1, 1, -1, 1,-1, 1, &
+ 1, 1,-1,-1, -1,-1,-1,-1, 0,-2, 2, 0, -1, 1, 1, 1, &
+!---------------- 46
+ 0, 2, 0, 2, 0, 0,-2, 0, 1, 1,-1,-1, 1,-1, 1, 1, &
+ 1, 1,-1, 1, -1, 1,-1,-1, 0, 0, 2, 0, -1,-1, 1, 1, &
+ 1,-1, 1, 1, 0,-2, 0,-2, 1, 1,-1,-1, -1, 1,-1, 1, &
+ 1, 1, 1, 1, 0, 2,-2, 0, 1,-1,-1,-1, -1,-1, 1,-1, &
+!---------------- 47
+ 0, 2, 0, 2, 0, 0, 2, 0, 1,-1, 1, 1, 1, 1,-1,-1, &
+ 1, 1,-1, 1, 0, 0, 2, 2, 1,-1, 1,-1, -1,-1,-1,-1, &
+ 1,-1,-1,-1, -1, 1,-1,-1, 0, 2, 0, 2, -1,-1, 1, 1, &
+ 1, 1, 1, 1, -1,-1, 1, 1, 0, 0,-2, 0, -1, 1,-1,-1, &
+!---------------- 48
+ 0, 2,-2, 0, -1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,-2, &
+ 1, 1,-1,-1, 1,-1, 1,-1, 0, 0, 2, 2, -2, 0, 0, 0, &
+ 2, 0, 0, 0, 0, 2, 0, 2, -1, 1,-1,-1, -1,-1, 1,-1, &
+ 1, 1, 1, 1, 1,-1, 1,-1, -1, 1,-1,-1, 0, 0,-2, 0, &
+!---------------- 49
+ 0, 0, 2, 2, -1, 1,-1, 1, 1, 1,-1, 1, 0,-2, 0, 0, &
+ 1, 1,-1, 1, 1,-1,-1,-1, -1,-1, 1, 1, 0, 0, 2, 0, &
+ 2, 0, 0, 0, 0, 2, 0, 2, -1,-1, 1, 1, -1,-1,-1,-1, &
+ 1,-1, 1, 1, 1,-1,-1,-1, 0, 2,-2, 0, -2, 0, 0, 0, &
+!---------------- 50
+ 0, 2,-2, 0, 1, 1, 1, 1, 0, 0, 0, 2, 1,-1,-1,-1, &
+ 1,-1, 1, 1, -1,-1, 1,-1, 0, 0,-2,-2, -1, 1,-1, 1, &
+ 2, 0, 0, 0, 0,-2, 0, 0, -1, 1,-1, 1, -1, 1, 1, 1, &
+ 1,-1, 1,-1, 1, 1, 1, 1, 0, 2,-2, 0, -2, 0, 0, 0, &
+!---------------- 51
+ 0, 0, 2, 2, -1,-1, 1,-1, 0,-2, 0, 0, -1, 1,-1, 1, &
+ 1, 1,-1, 1, 0, 0, 2, 2, -2, 0, 0, 0, 0, 0, 0,-2, &
+ 0, 2, 0, 0, -2, 0, 0, 0, 0,-2, 0,-2, 1,-1, 1, 1, &
+ 0, 0, 2, 0, -2, 0, 0, 0, 0, 2,-2, 0, 1,-1,-1,-1, &
+!---------------- 52
+ 0, 0, 2, 2, 1, 1,-1, 1, 0, 2, 0, 0, 1,-1, 1,-1, &
+ 1,-1,-1,-1, 1, 1,-1, 1, 0, 0, 2, 2, -2, 0, 0, 0, &
+ 2, 0, 0, 0, 0, 0, 0,-2, -1, 1, 1, 1, -1, 1,-1, 1, &
+ 1, 1,-1,-1, -1,-1,-1,-1, 0,-2, 2, 0, -1, 1, 1, 1, &
+!---------------- 53
+ 0, 2,-2, 0, -1, 1, 1, 1, 0, 0, 0, 2, -1,-1,-1,-1, &
+ 0, 0, 2, 0, 2, 0, 0, 0, 0, 0,-2,-2, -1, 1,-1, 1, &
+ 0, 0, 0, 2, -2, 0, 0, 0, 0,-2, 0,-2, 1, 1,-1,-1, &
+ 1, 1, 1, 1, 0, 2,-2, 0, -2, 0, 0, 0, 0,-2, 0, 0, &
+!---------------- 54
+ 0, 2, 0, 2, -1, 1,-1,-1, 0, 0,-2, 0, -1,-1, 1, 1, &
+ 1, 1,-1, 1, 0, 0, 2, 2, 1,-1, 1,-1, -1,-1,-1,-1, &
+ 1, 1,-1,-1, 0,-2, 0,-2, 1,-1, 1, 1, -1, 1, 1, 1, &
+ 1, 1, 1, 1, -1,-1, 1, 1, 0, 0,-2, 0, -1, 1,-1,-1, &
+!---------------- 55
+ 0, 2, 0, 2, -1,-1, 1, 1, 0, 0, 2, 0, -1, 1,-1,-1, &
+ 1, 1,-1, 1, -1, 1,-1,-1, 0, 0, 2, 0, -1,-1, 1, 1, &
+ 1,-1, 1,-1, -1,-1, 1, 1, 0, 2, 0, 2, -1, 1,-1,-1, &
+ 1, 1, 1, 1, 0, 2,-2, 0, 1,-1,-1,-1, -1,-1, 1,-1, &
+!---------------- 56
+ 0, 0, 2, 2, -1,-1, 1,-1, 1,-1, 1,-1, 0, 2, 0, 0, &
+ 1, 1,-1, 1, 1,-1,-1,-1, -1,-1, 1, 1, 0, 0, 2, 0, &
+ 2, 0, 0, 0, 0, 2, 0, 2, -1,-1, 1, 1, -1,-1,-1,-1, &
+ 2, 0, 0, 0, 0,-2, 2, 0, -1, 1, 1, 1, -1, 1,-1,-1, &
+!---------------- 57
+ 0, 2,-2, 0, -1,-1,-1,-1, 1,-1,-1,-1, 0, 0, 0, 2, &
+ 2, 0, 0, 0, 0, 0,-2,-2, -1, 1,-1, 1, -1,-1, 1, 1, &
+ 2, 0, 0, 0, 0, 2, 0, 2, -1, 1,-1,-1, -1,-1, 1,-1, &
+ 1, 1, 1, 1, 1,-1, 1,-1, -1, 1,-1,-1, 0, 0,-2, 0, &
+!---------------- 58
+ 0, 2,-2, 0, 1, 1, 1, 1, -1, 1, 1, 1, 0, 0, 0,-2, &
+ 1, 1,-1, 1, 0, 0, 2, 2, -2, 0, 0, 0, 0, 0, 0,-2, &
+ 0, 2, 0, 0, -2, 0, 0, 0, 0,-2, 0,-2, 1,-1, 1, 1, &
+ 1,-1,-1,-1, 0, 2,-2, 0, -2, 0, 0, 0, 0, 0, 2, 0, &
+!---------------- 59
+ 0, 2,-2, 0, 0, 0, 0,-2, -1,-1,-1,-1, -1, 1, 1, 1, &
+ 1,-1, 1, 1, -1,-1, 1,-1, 0, 0,-2,-2, -1, 1,-1, 1, &
+ 2, 0, 0, 0, 0,-2, 0, 0, -1, 1,-1, 1, -1, 1, 1, 1, &
+ 1,-1, 1,-1, 1, 1, 1, 1, 0, 2,-2, 0, -2, 0, 0, 0/
+data umats/& ! Divide all these elements by 2 for simplicity:
+ 0, 0, 0, 2, 0, 0,-2, 0, 0,-2, 0, 0, 2, 0, 0, 0, &
+ 0, 0, 2, 0, 0, 0, 0,-2, 2, 0, 0, 0, 0,-2, 0, 0, &
+ 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0,-2, 0, 0,-2, 0, &
+ 0, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 0, &
+ 0, 0, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, &
+ 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0/
+
+data nei/ &
+!===== 0--3:
+18,12,25,43,32,56,36,37,38,42, &
+34,28,41,27,14,48,13,21,17,19, &
+18,12,23,43,30,49,29,37,33,35, &
+34,28,39,27,16,57,20,21,22,26, &
+!---- 4--7:
+20,54,52,22,40,24,32,25,42,31, &
+36,46,50,38,15,40,14,41,19,24, &
+13,48,45,17,31,15,30,23,35,40, &
+29,55,50,33,24,31,16,39,26,15, &
+!---- 8--9
+26,57,48,19,43,20,33,38,13,28, &
+42,56,53,35,27,36,22,17,29,12, &
+!---- 10:
+39,14,23,37,21,30,16,32,25,41, &
+!---- 11:
+34,34,18,18,18,34,34,18,34,18, &
+!==== 12--27:
+27, 0, 2, 9,14,13,15,16,24,20, & ! 12
+19, 8, 1, 6,15,12,14,17,25,21, &
+16, 5,10, 1,12,15,13,18,26,22, &
+39, 5, 7, 6,13,14,12,19,27,23, &
+!--
+14,10, 7, 3,18,17,19,12,20,24, & ! 16
+55, 6, 9, 1,19,16,18,13,21,25, &
+34, 0, 2,11,16,19,17,14,22,26, &
+13, 1, 5, 8,17,18,16,15,23,27, &
+!--
+26, 3, 8, 4,22,21,23,24,16,12, & ! 20
+37, 1, 3,10,23,20,22,25,17,13, &
+46, 9, 4, 3,20,23,21,26,18,14, &
+40,10, 6, 2,21,22,20,27,19,15, &
+!--
+41, 5, 7, 4,26,25,27,20,12,16, & ! 24
+31, 4,10, 0,27,24,26,21,13,17, &
+20, 7, 3, 8,24,27,25,22,14,18, &
+12, 1, 3, 9,25,26,24,23,15,19, &
+!----- 28--43:
+43, 1, 3, 8,30,29,31,32,40,36, & !28
+35, 9, 2, 7,31,28,30,33,41,37, &
+32, 6,10, 2,28,31,29,34,42,38, &
+25, 6, 4, 7,29,30,28,35,43,39, &
+!--
+30,10, 4, 0,34,33,35,28,36,40, & ! 32
+54, 7, 8, 2,35,32,34,29,37,41, &
+18, 1, 3,11,32,35,33,30,38,42, &
+29, 2, 6, 9,33,34,32,31,39,43, &
+!--
+42, 0, 9, 5,38,37,39,40,32,28, & ! 36
+21, 2, 0,10,39,36,38,41,33,29, &
+50, 8, 5, 0,36,39,37,42,34,30, &
+15,10, 7, 3,37,38,36,43,35,31, &
+!--
+23, 6, 4, 5,42,41,43,36,28,32, & ! 40
+24, 5,10, 1,43,40,42,37,29,33, &
+36, 4, 0, 9,40,43,41,38,30,34, &
+28, 2, 0, 8,41,42,40,39,31,35, &
+!------ 44--59:
+53, 9, 4, 6,45,46,47,56,48,52, & ! 44
+17, 6, 0, 4,44,47,46,57,49,53, &
+22, 1, 9, 5,47,44,45,58,50,54, &
+38, 6, 8, 2,46,45,44,59,51,55, &
+!--
+17, 8, 6, 1,49,50,51,52,44,56, & ! 48
+33, 2, 7, 9,48,51,50,53,45,57, &
+38, 7, 3, 5,51,48,49,54,46,58, &
+58, 7, 5, 8,50,49,48,55,47,59, &
+!--
+22, 4, 2, 6,53,54,55,48,56,44, & ! 52
+44, 9, 6, 4,52,55,54,49,57,45, &
+33, 4, 8, 0,55,52,53,50,58,46, &
+17, 3, 9, 7,54,53,52,51,59,47, &
+!--
+38, 0, 5, 9,57,58,59,44,52,48, & ! 56
+22, 8, 4, 3,56,59,58,45,53,49, &
+51, 5, 7, 8,59,56,57,46,54,50, &
+33, 5, 1, 7,58,57,56,47,55,51/
+data dcol10/ &
+!==== 0--3:
+ 4, 3,13, 4,14, 0, 0, 3, 2, 5, &
+ 8, 6,11, 8,13, 0, 0, 6, 4,10, & ! previous row *2
+ 1,12, 7, 1,11, 0, 0,12, 8, 5, & !
+ 2, 9,14, 2, 7, 0, 0, 9, 1,10, & !
+!---- 4--7:
+13, 2, 1, 7, 1,14, 0, 0, 2, 6, & ! previous row *2, except cols 1 and 2
+11, 4, 2,14, 2,13, 0, 0, 4,12, &
+ 7, 3, 4,13, 4,11, 0, 0, 8, 9, &
+14, 1, 3,11, 8, 7, 0, 0, 1, 3, &
+!---- 8--9:
+ 2, 1, 4, 8, 5, 1, 9, 6, 4, 0, &
+ 4, 2, 3, 1,10, 2, 3,12, 8, 0, &
+!---- 10:
+11,14,13,10, 5,13,11, 7, 7,14, &
+!---- 11:
+ 2, 8,13,10, 7,11,14, 1, 5, 4/
+data dcol12/ &
+!===== 12--27:
+10,12, 3, 0, & ! 12
+ 4,11, 0, 8, & ! 13
+12, 0, 1, 2, & ! 14
+12,13,12, 4, & ! 15
+!--
+ 3, 4, 0, 8, & ! 16
+ 1, 2, 3,11, & ! 17
+10,11,14, 2, & ! 18
+11, 5,11, 7, & ! 19
+!--
+ 1, 0,14, 2, & ! 20
+ 5, 9, 6,10, & ! 21
+ 4,12, 8,14, & ! 22
+ 9, 2, 0, 8, & ! 23
+!--
+ 3, 3, 7, 1, & ! 24
+ 6, 0, 8, 2, & ! 25
+14,14, 5,13, & ! 26
+ 5, 7,13, 5, & ! 27
+!------ 28--43:
+ 5, 9, 6, 0, & ! 28
+ 8, 7, 0, 1, & ! 29
+ 9, 0, 2, 4, & ! 30
+ 9,11, 9, 8, & ! 31
+!--
+ 6, 8, 0, 1, & ! 32
+ 2, 4, 6, 7, & ! 33
+ 5, 7,13, 1, & ! 34
+ 7,10, 7,14, & ! 35
+!--
+ 2, 0,13, 4, & ! 36
+10, 3,12, 5, & ! 37
+ 3, 9, 1,13, & ! 38
+ 3, 4, 0, 1, & ! 39
+!--
+ 6, 6,14, 2, & ! 40
+12, 0, 1, 4, & ! 41
+13,13,10,11, & ! 42
+10,14,11,10, & ! 43
+!------- 44--59:
+ 1, 3, 4, 2, & ! 44
+ 9,11, 5, 9, & ! 45
+11, 5, 8,11, & ! 46
+ 7, 7, 1,10, & ! 47
+!--
+ 4,11,12, 0, & ! 48
+ 8, 0, 9, 7, & ! 49
+12,12,10,13, & ! 50
+ 2, 4, 8, 6, & ! 51
+!--
+ 6,14, 5, 6, & ! 52
+ 4,12, 1, 8, & ! 53
+13,13, 4,10, & ! 54
+14, 5, 2,14, & ! 55
+!--
+ 2, 0, 6,13, & ! 56
+ 1,14, 3, 0, & ! 57
+ 3, 1, 2, 9, & ! 58
+ 3, 3,10, 7/ ! 59
+data nei0a/45,54, 46,59, 52,47, 55,50/ ! k=0--3
+data nei0b/57,53, 44,45, 58,56, 59,51,& ! k=4--5
+ 44,47, 53,52, 51,49, 58,59,& ! k=6--7
+ 54,58, 47,51, 44,46, 55,49/ ! k=8--9
+data nei17/48,45/
+data nei22/57,52/
+data nei33/59,49/
+data nei38/56,47/
+data jcora/6,3, 2,5, 6,3, 2,5/ ! k=0--3
+data jcorb/6,3,6,3, 2,5,2,5, 4,1,6,3, 2,5,6,3, 6,3,6,3, 2,5,6,3/
+data tcors/2,0,0,0, 0,2,0,0, 0,0,2,0, 0,0,0,2, & ! twice the identity
+ 1,1,-1,-1, 1,-1,-1,1, -1,1,-1,1, 1,1,1,1, & ! A_1
+ 1,-1,-1,-1, -1,-1,-1,1, 1,-1,1,1, -1,-1,1,-1, & ! A_2
+ 1,-1,1,-1, -1,-1,-1,-1, -1,-1,1,1, -1,1,1,-1, & ! B_1
+ 1,-1,1,1, 1,1,-1,1, 1,-1,-1,-1, 1,1,1,-1, & ! B_2
+ 1,1,1,1, -1,1,-1,1, 1,-1,-1,1, 1,1,-1,-1, & ! C_1
+ 1,1,-1,1, 1,-1,1,1, -1,-1,-1,1, -1,1,1,1, &
+ 2,0,2,0, 2,2,0,2, 0,0,0,2, -2,-2,-2,-2, & ! to 11, jcol=1
+ 2,0,2,2, 2,0,0,0, -2,-2,-2,-2, -2,0,0,-2, & ! to 11 jcol=2
+ 0,2,0,0, -2,0,-2,0, 2,0,0,2, 0,-2,0,-2, & ! to 11 jcol=3
+ 2,2,0,2, -2,0,-2,-2, 0,-2,0,-2, 0,0,2,0, & ! to 11 jcol=4
+ 1,1,1,-1, -1,1,1,1, -1,-1,1,-1, 1,-1,1,1, & ! >11 to>43,jcol=1
+ 1,-1,-1,1, 1,1,-1,-1, 1,1,1,1, -1,1,-1,1/ ! >11 to>43,jcol=2
+data kcor10a5/0,2,1, 0,1,2, 0,2,1, 0,1,2/
+data kcor10b1/0,1,2, 0,2,1, 1,2,0, 0,2,1, 1,0,2, 1,2,0/
+data kcor10b2/0,2,1, 0,1,2, 0,2,1, 1,2,0, 0,1,2, 2,1,0/
+
+data kcor12b0/0,1,2,2, 1,2,0,0, 2,0,1,2, 1,1,0,0, &
+ 0,1,2,2, 1,2,0,0, 2,0,1,2, 1,1,0,0, &
+ 0,1,2,2, 0,1,0,1, 1,0,2,2, 1,0,0,0/
+data kcor17c0/0,1,2/
+data kcor22c0/2,1,0/
+data kcor33c0/0,2,1/
+data kcor38c0/0,1,2/
+data kcor44c0/1,0,2/
+data kcor51c0/2,1,0/
+data kcor53c0/1,0,2/
+data kcor58c0/1,0,2/
+data twt10a5/ &
+ 0,-1,-1, 0,-1, 2, 0, 0, 1,-1, & !
+ 0,-1, 0,-1,-1, 2,-1, 1, 0, 0, & !
+ 1, 0,-1,-1, 0, 2,-1, 0, 0,-1/ !
+data twt10b1/ &
+ 0, 2, 0,-1,-1,-1, 1,-1, 0, 0, & !
+ 1, 2, 0,-1, 0, 0, 0,-1,-1,-1, & !
+ 0, 2, 1, 0,-1,-1, 0, 0,-1,-1/
+data twt10b2/ &
+-1, 0, 2, 1, 0,-1,-1, 0, 0,-1, & !
+-1, 0, 2, 0,-1, 0,-1, 1,-1, 0, & !
+ 0, 1, 2, 0,-1,-1, 0, 0,-1,-1/ !
+data twt12c0/ &
+ 2, 0, 1, 0,-1, 0,-1,-1, 0,-1, & ! 0
+ 2, 0, 0, 1, 0,-1,-1, 0,-1,-1, & ! 0
+ 2, 1, 0, 0,-1,-1, 0,-1,-1, 0/ ! 0
+data qwt10a/ &
+! -------------------------------------------- 0
+ 2, 0,-1, 0, 1, 0,-1,-1,-1, 0, & ! 0
+ 0, 2, 1, 0,-1,-1, 0, 0,-1,-1, & ! 1
+-1, 0, 2, 1, 0,-1,-1, 0, 0,-1, & ! 2
+ 0,-1, 0, 2, 1,-1,-1,-1, 0, 0, & ! 3
+ 0,-1,-1, 0, 2,-1, 0, 0,-1, 1, & ! 4
+ 0,-1,-1, 0,-1, 2, 0, 0, 1,-1, & ! 5
+-1, 0,-1, 0,-1, 0, 2,-1, 1, 0, & ! 6
+-1, 0, 1, 0,-1, 0,-1, 2,-1, 0, & ! 7
+ 0,-1,-1, 0,-1, 1, 0, 0, 2,-1, & ! 8
+-1,-1, 0,-1, 0, 0, 0, 1,-1, 2/ ! 9
+data qwt10b/ &
+! -------------------------------------------- 4
+ 2, 0,-1,-1, 0, 1,-1, 0, 0,-1, & ! 0
+ 0, 2, 0,-1,-1,-1, 1,-1, 0, 0, & ! 1
+-1, 0, 2, 1, 0,-1,-1, 0, 0,-1, & ! 2
+-1, 0, 1, 2, 0,-1,-1, 0, 0,-1, & ! 3
+ 0,-1, 0, 1, 2,-1,-1,-1, 0, 0, & ! 4
+ 0,-1,-1, 0,-1, 2, 0, 0, 1,-1, & ! 5
+-1, 0,-1,-1, 0,-1, 2, 0, 0, 1, & ! 6
+-1,-1, 0,-1, 0, 0, 0, 2,-1, 1, & ! 7
+-1, 0,-1, 0,-1, 0, 1,-1, 2, 0, & ! 8
+-1,-1, 0,-1, 0, 0, 0, 1,-1, 2/ ! 9
+data qwt10c/ &
+! -------------------------------------------- 8
+ 2, 0,-1,-1, 0, 1,-1, 0, 0,-1, & ! 0
+ 1, 2, 0,-1, 0, 0, 0,-1,-1,-1, & ! 1
+-1, 0, 2, 1, 0,-1,-1, 0, 0,-1, & ! 2
+-1,-1, 0, 2, 0, 0, 0,-1, 1,-1, & ! 3
+ 0,-1,-1, 0, 2,-1, 0, 0,-1, 1, & ! 4
+ 1, 0,-1,-1, 0, 2,-1, 0, 0,-1, & ! 5
+ 0, 1, 0,-1,-1,-1, 2,-1, 0, 0, & ! 6
+-1, 0, 1, 0,-1, 0,-1, 2,-1, 0, & ! 7
+-1,-1, 0, 1, 0, 0, 0,-1, 2,-1, & ! 8
+ 0,-1,-1, 0, 1,-1, 0, 0,-1, 2/ ! 9
+data qwt10d/ &
+! -------------------------------------------- 10
+ 2, 1, 0,-1, 0, 0, 0,-1,-1,-1, & ! 0
+ 0, 2, 0,-1,-1,-1, 1,-1, 0, 0, & ! 1
+-1, 0, 2, 0,-1, 0,-1, 1,-1, 0, & ! 2
+ 0,-1, 0, 2, 1,-1,-1,-1, 0, 0, & ! 3
+ 0,-1, 0, 1, 2,-1,-1,-1, 0, 0, & ! 4
+ 0,-1, 0,-1,-1, 2,-1, 1, 0, 0, & ! 5
+ 0, 1, 0,-1,-1,-1, 2,-1, 0, 0, & ! 6
+ 0,-1, 0,-1,-1, 1,-1, 2, 0, 0, & ! 7
+ 0,-1,-1, 0,-1, 1, 0, 0, 2,-1, & ! 8
+-1, 0,-1,-1, 0,-1, 1, 0, 0, 2/ ! 9
+data qwt10e/ &
+! -------------------------------------------- 11
+ 2, 0,-1, 0, 1, 0,-1,-1,-1, 0, & ! 0
+ 0, 2, 1, 0,-1,-1, 0, 0,-1,-1, & ! 1
+ 0, 1, 2, 0,-1,-1, 0, 0,-1,-1, & ! 2
+-1,-1, 0, 2, 0, 0, 0,-1, 1,-1, & ! 3
+ 1, 0,-1, 0, 2, 0,-1,-1,-1, 0, & ! 4
+ 0,-1, 0,-1,-1, 2,-1, 1, 0, 0, & ! 5
+-1, 0,-1,-1, 0,-1, 2, 0, 0, 1, & ! 6
+ 0,-1, 0,-1,-1, 1,-1, 2, 0, 0, & ! 7
+-1,-1, 0, 1, 0, 0, 0,-1, 2,-1, & ! 8
+-1, 0,-1,-1, 0,-1, 1, 0, 0, 2/ ! 9
+data qwt12a/ &
+! -------------------------------------------- 12
+ 2, 0, 0, 1, 0,-1,-1, 0,-1,-1, & ! 0
+ 1, 2, 0, 0,-1,-1, 0,-1,-1, 0, & ! 1
+ 1, 0, 2, 0,-1, 0,-1,-1, 0,-1, & ! 2
+ 1, 0, 0, 2, 0,-1,-1, 0,-1,-1, & ! 3
+-1,-1,-1,-1, 2, 1, 1, 0, 0, 0, & ! 4
+-1,-1,-1,-1, 1, 2, 1, 0, 0, 0, & ! 5
+-1,-1,-1,-1, 1, 1, 2, 0, 0, 0, & ! 6
+-1,-1,-1,-1, 0, 0, 0, 2, 1, 1, & ! 7
+-1,-1,-1,-1, 0, 0, 0, 1, 2, 1, & ! 8
+-1,-1,-1,-1, 0, 0, 0, 1, 1, 2/ ! 9
+data qwt12b/ &
+! -------------------------------------------- 44
+ 2, 0, 0, 1, 0,-1,-1, 0,-1,-1, & ! 0
+ 1, 2, 0, 0,-1,-1, 0,-1,-1, 0, & ! 1
+ 1, 0, 2, 0,-1, 0,-1,-1, 0,-1, & ! 2
+ 1, 0, 0, 2, 0,-1,-1, 0,-1,-1, & ! 3
+-1,-1,-1,-1, 2, 1, 1, 0, 0, 0, & ! 4
+-1,-1,-1,-1, 1, 2, 1, 0, 0, 0, & ! 5
+-1,-1,-1,-1, 1, 1, 2, 0, 0, 0, & ! 6
+-1,-1,-1,-1, 0, 0, 0, 2, 1, 1, & ! 7
+-1,-1,-1,-1, 0, 0, 0, 1, 2, 1, & ! 8
+-1,-1,-1,-1, 0, 0, 0, 1, 1, 2/! 9
+data qwt12b0/ &
+ 2, 0, 0, 1, 0,-1,-1, 0,-1,-1, & ! 0
+ 2, 1, 0, 0,-1,-1, 0,-1,-1, 0, & ! 12
+ 2, 0, 1, 0,-1, 0,-1,-1, 0,-1/! 0
+data tperms/ &
+0,1,2,3,4,5,6,7,8,9, &
+9,8,1,7,3,0,2,5,6,4, & ! 1
+6,4,5,1,9,7,8,0,2,3, & ! 2
+7,3,8,9,1,2,0,5,6,4, & ! 3
+4,6,3,5,9,7,8,2,0,1, & ! 4
+8,9,7,2,0,3,1,5,6,4, & ! 5
+5,2,6,4,9,7,8,3,1,0, & ! 6
+8,5,7,2,3,6,0,9,1,4, & ! 7
+1,6,9,7,2,0,8,4,5,3, & ! 8
+5,0,4,9,7,8,1,3,6,2, & ! 9
+6,8,3,4,9,1,5,2,0,7, & ! 10
+0,5,4,6,9,7,8,1,3,2, & ! 11
+0,7,9,8,2,1,3,5,6,4/ ! 12
+data perm10/ &
+! -------------------------------- 0
+1,9,8,2,0,6,7,4,5,3, & ! 0
+9,1,0,3,7,8,6,2,4,5, & ! 1
+6,4,3,0,1,8,5,7,2,9, & ! 2
+1,9,8,2,0,6,4,7,5,3, & ! 3
+4,5,9,7,3,6,2,1,8,0, & ! 4
+9,7,5,2,8,1,3,6,0,4, & ! 5
+5,6,4,3,7,2,1,8,0,9, & ! 6
+9,1,0,3,4,8,6,2,7,5, & ! 7
+1,9,5,4,6,0,7,2,3,8, & ! 8
+9,4,3,7,8,1,5,0,6,2, & ! 9
+! -------------------------------- 1
+1,9,8,2,0,6,7,4,5,3, & ! 0
+9,1,0,3,7,8,6,2,4,5, & ! 1
+6,4,3,0,1,8,5,7,2,9, & ! 2
+2,5,6,1,0,8,7,4,9,3, & ! 3
+7,9,5,4,3,8,1,2,6,0, & ! 4
+4,6,8,2,5,3,1,7,0,9, & ! 5
+9,8,7,3,4,1,2,6,0,5, & ! 6
+5,2,0,3,7,6,8,1,4,9, & ! 7
+2,5,9,7,8,0,4,1,3,6, & ! 8
+5,7,3,4,6,2,9,0,8,1, & ! 9
+! -------------------------------- 2
+2,5,6,1,0,8,4,7,9,3, & ! 0
+5,2,0,3,4,6,8,1,7,9, & ! 1
+8,7,3,0,2,6,9,4,1,5, & ! 2
+2,5,6,1,0,8,7,4,9,3, & ! 3
+7,9,5,4,3,8,1,2,6,0, & ! 4
+9,7,5,2,8,1,3,6,0,4, & ! 5
+9,8,7,3,4,1,2,6,0,5, & ! 6
+5,2,0,3,7,6,8,1,4,9, & ! 7
+2,5,9,7,8,0,4,1,3,6, & ! 8
+5,7,3,4,6,2,9,0,8,1, & ! 9
+! -------------------------------- 3
+2,5,6,1,0,8,4,7,9,3, & ! 0
+5,2,0,3,4,6,8,1,7,9, & ! 1
+8,7,3,0,2,6,9,4,1,5, & ! 2
+1,9,8,2,0,6,4,7,5,3, & ! 3
+4,5,9,7,3,6,2,1,8,0, & ! 4
+4,6,8,2,5,3,1,7,0,9, & ! 5
+5,6,4,3,7,2,1,8,0,9, & ! 6
+9,1,0,3,4,8,6,2,7,5, & ! 7
+1,9,5,4,6,0,7,2,3,8, & ! 8
+9,4,3,7,8,1,5,0,6,2, & ! 9
+! -------------------------------- 4
+3,4,6,8,7,0,5,1,2,9, & ! 0
+9,1,6,4,8,7,0,5,3,2, & ! 1
+7,9,1,0,3,5,8,6,2,4, & ! 2
+6,1,0,2,5,7,9,3,8,4, & ! 3
+5,6,1,0,2,4,7,9,3,8, & ! 4
+4,6,8,2,5,3,1,7,0,9, & ! 5
+4,5,6,7,3,9,2,1,8,0, & ! 6
+4,8,9,7,3,6,2,1,5,0, & ! 7
+5,2,8,9,7,6,0,4,1,3, & ! 8
+7,6,1,9,8,3,5,0,4,2, & ! 9
+! -------------------------------- 5
+3,4,6,8,7,0,5,1,2,9, & ! 0
+4,3,7,9,5,6,0,8,1,2, & ! 1
+6,4,3,0,1,8,5,7,2,9, & ! 2
+6,1,0,2,5,7,9,3,8,4, & ! 3
+9,8,2,0,1,7,4,5,3,6, & ! 4
+4,6,8,2,5,3,1,7,0,9, & ! 5
+7,9,8,4,3,5,1,2,6,0, & ! 6
+4,8,9,7,3,6,2,1,5,0, & ! 7
+9,1,6,5,4,8,0,7,2,3, & ! 8
+4,8,2,5,6,3,9,0,7,1, & ! 9
+! -------------------------------- 6
+3,7,8,6,4,0,9,2,1,5, & ! 0
+0,2,8,9,1,3,5,7,4,6, & ! 1
+7,9,1,0,3,5,8,6,2,4, & ! 2
+8,2,0,1,9,4,5,3,6,7, & ! 3
+9,8,2,0,1,7,4,5,3,6, & ! 4
+7,8,6,1,9,3,2,4,0,5, & ! 5
+7,9,8,4,3,5,1,2,6,0, & ! 6
+7,6,5,4,3,8,1,2,9,0, & ! 7
+9,1,6,5,4,8,0,7,2,3, & ! 8
+4,8,2,5,6,3,9,0,7,1, & ! 9
+! -------------------------------- 7
+3,7,8,6,4,0,9,2,1,5, & ! 0
+4,3,7,9,5,6,0,8,1,2, & ! 1
+8,9,1,6,4,2,7,0,5,3, & ! 2
+8,2,0,1,9,4,5,3,6,7, & ! 3
+5,6,1,0,2,4,7,9,3,8, & ! 4
+7,8,6,1,9,3,2,4,0,5, & ! 5
+4,5,6,7,3,9,2,1,8,0, & ! 6
+7,6,5,4,3,8,1,2,9,0, & ! 7
+5,2,8,9,7,6,0,4,1,3, & ! 8
+7,6,1,9,8,3,5,0,4,2, & ! 9
+! -------------------------------- 8
+3,7,8,6,4,0,9,2,1,5, & ! 0
+0,1,6,5,2,3,9,4,7,8, & ! 1
+5,6,1,0,2,7,4,9,3,8, & ! 2
+8,6,4,3,7,2,1,5,0,9, & ! 3
+4,6,8,7,3,5,1,2,9,0, & ! 4
+0,1,6,7,3,2,9,5,8,4, & ! 5
+3,0,1,9,4,7,2,6,8,5, & ! 6
+5,2,0,3,7,6,8,1,4,9, & ! 7
+4,8,2,0,3,6,9,5,1,7, & ! 8
+1,6,8,2,0,9,4,7,5,3, & ! 9
+! -------------------------------- 9
+3,7,8,6,4,0,9,2,1,5, & ! 0
+0,3,7,8,2,1,4,9,6,5, & ! 1
+2,0,1,6,5,8,3,9,4,7, & ! 2
+8,6,4,3,7,2,1,5,0,9, & ! 3
+7,8,6,4,3,9,2,1,5,0, & ! 4
+0,1,6,7,3,2,9,5,8,4, & ! 5
+3,0,2,5,7,4,1,8,6,9, & ! 6
+9,1,0,3,4,8,6,2,7,5, & ! 7
+4,8,2,0,3,6,9,5,1,7, & ! 8
+2,8,6,1,0,5,7,4,9,3, & ! 9
+! -------------------------------- 10
+1,0,3,7,9,6,2,4,5,8, & ! 0
+5,2,8,7,6,4,0,9,3,1, & ! 1
+5,6,1,9,7,2,4,0,8,3, & ! 2
+2,5,4,3,0,8,9,6,7,1, & ! 3
+7,8,2,0,3,9,6,5,1,4, & ! 4
+8,9,1,6,7,2,4,0,5,3, & ! 5
+2,0,3,4,8,5,1,7,6,9, & ! 6
+3,7,9,8,4,0,5,1,2,6, & ! 7
+3,7,6,5,4,0,8,1,2,9, & ! 8
+6,1,9,4,5,7,0,8,3,2, & ! 9
+! -------------------------------- 11
+3,4,5,2,0,7,6,9,8,1, & ! 0
+7,3,0,1,9,8,4,2,6,5, & ! 1
+2,0,3,7,8,5,1,4,9,6, & ! 2
+9,5,4,3,7,1,2,6,0,8, & ! 3
+0,1,6,4,3,2,9,8,5,7, & ! 4
+4,6,1,9,5,3,8,0,7,2, & ! 5
+8,7,9,5,2,6,3,1,4,0, & ! 6
+1,9,7,8,6,0,5,3,2,4, & ! 7
+6,8,2,0,1,4,7,5,3,9, & ! 8
+5,2,8,6,4,9,0,7,1,3/ ! 9
+data perm12/ &
+! -------------------------------- 12
+0,4,7,3,1,9,6,2,8,5, & ! 0
+2,1,7,3,8,9,6,4,5,0, & ! 1
+2,7,1,3,4,0,5,8,6,9, & ! 2
+4,3,0,9,7,5,2,6,1,8, & ! 3
+! -------------------------------- 13
+0,3,4,7,8,5,2,9,6,1, & ! 0
+3,8,2,4,0,7,5,9,1,6, & ! 1
+8,5,6,3,4,9,7,2,1,0, & ! 2
+5,8,7,0,4,9,3,1,2,6, & ! 3
+! -------------------------------- 14
+0,9,1,6,5,2,8,4,3,7, & ! 0
+9,6,7,4,3,5,8,0,2,1, & ! 1
+6,9,1,8,5,0,4,3,2,7, & ! 2
+9,6,7,4,3,2,8,0,5,1, & ! 3
+! -------------------------------- 15
+0,5,2,8,9,1,6,7,3,4, & ! 0
+3,4,2,8,6,7,9,5,1,0, & ! 1
+7,2,9,5,8,6,1,0,4,3, & ! 2
+8,3,6,5,7,9,2,0,1,4, & ! 3
+! -------------------------------- 16
+0,2,5,8,7,4,3,9,6,1, & ! 0
+1,6,0,2,3,5,8,7,4,9, & ! 1
+9,7,6,4,0,1,2,3,8,5, & ! 2
+9,7,6,4,0,1,5,3,8,2, & ! 3
+! -------------------------------- 17
+0,5,2,8,7,3,4,9,1,6, & ! 0
+2,3,1,7,5,6,8,9,0,4, & ! 1
+2,1,7,3,4,9,6,8,5,0, & ! 2
+5,7,0,8,6,1,9,3,4,2, & ! 3
+! -------------------------------- 18
+0,4,7,3,2,8,5,1,9,6, & ! 0
+4,0,3,9,7,8,5,6,2,1, & ! 1
+4,3,0,9,6,1,2,7,5,8, & ! 2
+1,6,0,2,7,5,9,3,4,8, & ! 3
+! -------------------------------- 19
+0,9,6,1,2,5,8,3,4,7, & ! 0
+7,9,5,2,3,0,4,1,8,6, & ! 1
+6,1,8,9,4,3,2,7,5,0, & ! 2
+8,6,5,3,2,7,1,4,0,9, & ! 3
+! -------------------------------- 20
+0,7,3,4,5,2,8,6,1,9, & ! 0
+8,6,5,3,2,0,1,4,7,9, & ! 1
+0,1,5,4,9,7,2,3,8,6, & ! 2
+5,7,8,0,1,6,2,4,3,9, & ! 3
+! -------------------------------- 21
+0,7,4,3,1,6,9,2,5,8, & ! 0
+2,7,1,3,8,0,5,4,6,9, & ! 1
+2,1,7,3,4,9,6,8,5,0, & ! 2
+3,8,2,4,9,7,6,0,1,5, & ! 3
+! -------------------------------- 22
+0,2,5,8,9,6,1,7,4,3, & ! 0
+1,6,2,0,5,3,8,4,7,9, & ! 1
+2,1,3,7,9,4,0,5,8,6, & ! 2
+5,0,7,8,3,2,4,6,9,1, & ! 3
+! -------------------------------- 23
+0,9,1,6,5,2,8,4,3,7, & ! 0
+7,2,5,9,6,0,1,4,8,3, & ! 1
+9,6,7,4,3,2,1,0,5,8, & ! 2
+3,8,4,2,7,9,5,1,0,6, & ! 3
+! -------------------------------- 24
+0,1,9,6,4,7,3,5,8,2, & ! 0
+7,9,2,5,0,3,4,8,1,6, & ! 1
+3,2,4,8,5,0,1,6,9,7, & ! 2
+8,6,3,5,0,4,1,7,2,9, & ! 3
+! -------------------------------- 25
+0,2,5,8,7,4,3,9,6,1, & ! 0
+9,7,6,4,0,8,5,3,1,2, & ! 1
+5,7,8,0,4,3,2,1,6,9, & ! 2
+3,4,8,2,1,6,0,7,5,9, & ! 3
+! -------------------------------- 26
+0,8,5,2,3,4,7,1,6,9, & ! 0
+6,8,1,9,7,0,5,4,2,3, & ! 1
+7,5,9,2,1,6,8,3,4,0, & ! 2
+5,8,7,0,4,9,3,1,2,6, & ! 3
+! -------------------------------- 27
+0,4,7,3,1,9,6,2,8,5, & ! 0
+4,3,0,9,7,1,2,6,5,8, & ! 1
+4,0,3,9,6,8,5,7,2,1, & ! 2
+9,7,6,4,3,8,2,0,1,5, & ! 3
+! -------------------------------- 28
+0,4,7,3,1,9,6,2,8,5, & ! 0
+2,1,7,3,8,9,6,4,5,0, & ! 1
+2,7,1,3,4,0,5,8,6,9, & ! 2
+4,0,3,9,6,8,1,7,2,5, & ! 3
+! -------------------------------- 29
+0,3,4,7,8,5,2,9,6,1, & ! 0
+3,8,2,4,0,7,5,9,1,6, & ! 1
+8,5,6,3,4,9,7,2,1,0, & ! 2
+5,8,7,0,4,9,3,1,2,6, & ! 3
+! -------------------------------- 30
+0,9,1,6,5,2,8,4,3,7, & ! 0
+9,6,7,4,3,5,8,0,2,1, & ! 1
+7,2,5,9,6,8,3,4,0,1, & ! 2
+9,6,7,4,3,2,8,0,5,1, & ! 3
+! -------------------------------- 31
+0,9,1,6,5,2,8,4,3,7, & ! 0
+3,4,2,8,6,7,9,5,1,0, & ! 1
+7,2,9,5,8,6,1,0,4,3, & ! 2
+8,3,6,5,7,9,2,0,1,4, & ! 3
+! -------------------------------- 32
+0,2,5,8,7,4,3,9,6,1, & ! 0
+5,7,8,0,4,6,9,1,3,2, & ! 1
+9,7,6,4,0,1,2,3,8,5, & ! 2
+9,7,6,4,0,1,5,3,8,2, & ! 3
+! -------------------------------- 33
+0,8,2,5,6,1,9,4,3,7, & ! 0
+2,3,1,7,5,6,8,9,0,4, & ! 1
+1,2,6,0,4,9,7,5,8,3, & ! 2
+5,7,0,8,6,1,9,3,4,2, & ! 3
+! -------------------------------- 34
+0,7,4,3,1,6,9,2,5,8, & ! 0
+4,0,3,9,7,8,5,6,2,1, & ! 1
+4,3,0,9,6,1,2,7,5,8, & ! 2
+9,7,4,6,8,3,5,1,0,2, & ! 3
+! -------------------------------- 35
+0,9,6,1,2,5,8,3,4,7, & ! 0
+7,9,5,2,3,0,4,1,8,6, & ! 1
+6,1,8,9,4,3,2,7,5,0, & ! 2
+8,6,5,3,2,7,1,4,0,9, & ! 3
+! -------------------------------- 36
+0,7,3,4,5,2,8,6,1,9, & ! 0
+8,6,5,3,2,0,1,4,7,9, & ! 1
+0,1,5,4,9,7,2,3,8,6, & ! 2
+5,7,8,0,1,6,2,4,3,9, & ! 3
+! -------------------------------- 37
+0,4,7,3,2,8,5,1,9,6, & ! 0
+2,7,1,3,8,0,5,4,6,9, & ! 1
+2,1,7,3,4,9,6,8,5,0, & ! 2
+4,9,0,3,2,1,7,8,5,6, & ! 3
+! -------------------------------- 38
+0,4,3,7,9,1,6,8,2,5, & ! 0
+2,7,1,3,8,0,5,4,6,9, & ! 1
+2,1,3,7,9,4,0,5,8,6, & ! 2
+5,0,7,8,3,2,4,6,9,1, & ! 3
+! -------------------------------- 39
+0,5,2,8,9,1,6,7,3,4, & ! 0
+1,0,6,2,7,8,5,3,9,4, & ! 1
+9,6,7,4,3,2,1,0,5,8, & ! 2
+3,8,4,2,7,9,5,1,0,6, & ! 3
+! -------------------------------- 40
+0,2,5,8,7,4,3,9,6,1, & ! 0
+7,9,2,5,0,3,4,8,1,6, & ! 1
+3,2,4,8,5,0,1,6,9,7, & ! 2
+8,6,3,5,0,4,1,7,2,9, & ! 3
+! -------------------------------- 41
+0,1,9,6,4,7,3,5,8,2, & ! 0
+9,7,6,4,0,8,5,3,1,2, & ! 1
+6,1,9,8,3,4,0,5,7,2, & ! 2
+3,4,8,2,1,6,0,7,5,9, & ! 3
+! -------------------------------- 42
+0,8,5,2,3,4,7,1,6,9, & ! 0
+6,8,1,9,7,0,5,4,2,3, & ! 1
+7,5,9,2,1,6,8,3,4,0, & ! 2
+5,8,7,0,4,9,3,1,2,6, & ! 3
+! -------------------------------- 43
+0,4,7,3,1,9,6,2,8,5, & ! 0
+4,3,0,9,7,1,2,6,5,8, & ! 1
+4,0,3,9,6,8,5,7,2,1, & ! 2
+9,6,7,4,0,5,1,3,2,8, & ! 3
+! -------------------------------- 44
+0,5,8,2,3,7,4,1,9,6, & ! 0
+2,1,3,7,5,4,0,9,8,6, & ! 1
+1,6,2,0,4,3,8,5,7,9, & ! 2
+2,3,7,1,0,5,4,6,9,8, & ! 3
+! -------------------------------- 45
+0,1,6,9,7,4,3,8,5,2, & ! 0
+3,2,8,4,9,5,7,0,6,1, & ! 1
+0,4,5,1,6,8,3,2,7,9, & ! 2
+7,9,5,2,1,0,6,3,8,4, & ! 3
+! -------------------------------- 46
+0,6,1,9,8,2,5,7,3,4, & ! 0
+7,5,2,9,6,3,8,4,1,0, & ! 1
+6,8,1,9,7,2,3,4,0,5, & ! 2
+6,8,9,1,0,4,5,2,7,3, & ! 3
+! -------------------------------- 47
+0,9,1,6,4,3,7,5,2,8, & ! 0
+6,1,9,8,3,7,2,5,4,0, & ! 1
+7,9,2,5,8,3,4,0,1,6, & ! 2
+7,9,2,5,0,1,4,8,3,6, & ! 3
+! -------------------------------- 48
+0,4,7,3,2,8,5,1,9,6, & ! 0
+3,2,4,8,6,0,1,5,9,7, & ! 1
+0,4,1,5,8,6,9,7,2,3, & ! 2
+8,6,3,5,0,4,1,7,2,9, & ! 3
+! -------------------------------- 49
+0,3,7,4,6,9,1,5,8,2, & ! 0
+8,5,3,6,9,2,7,1,4,0, & ! 1
+0,5,1,4,3,2,7,9,6,8, & ! 2
+3,8,4,2,7,9,5,1,0,6, & ! 3
+! -------------------------------- 50
+0,5,8,2,1,9,6,3,7,4, & ! 0
+7,2,5,9,4,8,3,6,0,1, & ! 1
+0,1,5,4,9,7,2,3,8,6, & ! 2
+3,4,8,2,1,6,0,7,5,9, & ! 3
+! -------------------------------- 51
+0,2,5,8,7,4,3,9,6,1, & ! 0
+2,1,7,3,8,9,6,4,5,0, & ! 1
+1,0,2,6,9,7,5,8,3,4, & ! 2
+1,6,0,2,7,5,9,3,4,8, & ! 3
+! -------------------------------- 52
+0,2,8,5,4,7,3,6,9,1, & ! 0
+3,2,8,4,9,5,7,0,6,1, & ! 1
+0,4,5,1,6,8,3,2,7,9, & ! 2
+7,9,5,2,1,0,6,3,8,4, & ! 3
+! -------------------------------- 53
+0,5,8,2,3,7,4,1,9,6, & ! 0
+1,2,0,6,8,4,3,9,5,7, & ! 1
+1,6,2,0,4,3,8,5,7,9, & ! 2
+2,3,7,1,0,5,4,6,9,8, & ! 3
+! -------------------------------- 54
+0,5,2,8,7,3,4,9,1,6, & ! 0
+6,1,9,8,3,7,2,5,4,0, & ! 1
+6,9,1,8,5,0,4,3,2,7, & ! 2
+7,9,2,5,0,1,4,8,3,6, & ! 3
+! -------------------------------- 55
+0,8,2,5,6,1,9,4,3,7, & ! 0
+7,5,2,9,6,3,8,4,1,0, & ! 1
+7,5,2,9,6,1,0,4,3,8, & ! 2
+6,8,9,1,0,4,5,2,7,3, & ! 3
+! -------------------------------- 56
+0,3,4,7,8,5,2,9,6,1, & ! 0
+8,5,3,6,9,2,7,1,4,0, & ! 1
+0,5,1,4,3,2,7,9,6,8, & ! 2
+0,5,4,1,6,9,8,2,3,7, & ! 3
+! -------------------------------- 57
+0,7,4,3,1,6,9,2,5,8, & ! 0
+0,1,4,5,7,3,2,8,9,6, & ! 1
+0,4,1,5,8,6,9,7,2,3, & ! 2
+8,6,3,5,0,4,1,7,2,9, & ! 3
+! -------------------------------- 58
+0,4,7,3,1,9,6,2,8,5, & ! 0
+2,1,7,3,8,9,6,4,5,0, & ! 1
+1,0,2,6,9,7,5,8,3,4, & ! 2
+2,7,3,1,6,8,9,0,4,5, & ! 3
+! -------------------------------- 59
+0,9,6,1,2,5,8,3,4,7, & ! 0
+7,2,5,9,4,8,3,6,0,1, & ! 1
+0,1,5,4,9,7,2,3,8,6, & ! 2
+3,4,8,2,1,6,0,7,5,9/ ! 3
+!======
+data perms/ &
+3,2,1,0,4,6,5,7,8,9, & ! 4
+2,3,0,1,6,5,4,7,8,9, & ! 5
+1,0,3,2,5,4,6,7,8,9, & ! 6
+3,2,1,0,4,5,6,7,9,8, & ! 7
+2,3,0,1,4,5,6,9,8,7, & ! 8
+1,0,3,2,4,5,6,8,7,9/ ! 9
+end module jp_pbfil2
+!#
diff --git a/src/mgbf/jp_pbfil3.f90 b/src/mgbf/jp_pbfil3.f90
new file mode 100644
index 0000000000..61a6932577
--- /dev/null
+++ b/src/mgbf/jp_pbfil3.f90
@@ -0,0 +1,2620 @@
+module jp_pbfil3
+!$$$ module documentation block
+! . . . .
+! module: jp_pbfil3
+! prgmmr: purser org: NOAA/EMC date: 2021-08
+!
+! abstract: Codes for the beta line filters
+!
+! module history log:
+!
+! Subroutines Included:
+! t22_to_3 -
+! t2_to_3 -
+! t3_to_22 -
+! t33_to_6 -
+! t3_to_6 -
+! t6_to_33 -
+! t44_to_10 -
+! t4_to_10 -
+! t10_to_44 -
+! finmomtab -
+! inimomtab -
+! tritform -
+! tritformi -
+! triad -
+! gettrilu -
+! querytcol -
+! hextform -
+! hextformi -
+! hexad -
+! gethexlu -
+! queryhcol -
+! dectform -
+! dectformi -
+! decad -
+! getdeclu -
+! querydcol -
+! standardizeb -
+! hstform -
+! hstformi -
+! blinfil -
+! dibeta -
+! dibetat -
+!
+! Functions Included:
+!
+! remarks:
+! The routines of this module mostly involve the beta line filters.
+! Versions of these routines are provided in 2D, 3D and 4D, based respectively
+! on the Triad (3-lines), Hexad (6-lines), and Decad (10-lines) algorithms.
+! Some technical explanations are provided in the series of office notes,
+! ON498, ON499, ON500.
+!
+! The style of line filtering is the "Dibeta" combination of two
+! nonnegatively-weighted consecutive-imteger-half-span beta filters, whose
+! normalization coefficients are stored in the table, "bnorm" and whose
+! second moments (spread**2) are stored in the table "bsprds"; these
+! moment tables must be initialized in subr. inimomtab before any filtering
+! can be done. The max-halp-span size of the table is set by the user, so
+! the tables use allocatable space (in module jp_pbfil2); to deallocate this
+! storage, the user must invoke fintabmom once all filtering operations
+! have been completed.
+!
+! Aspect tensors in N dimensions are positive-definite and symmetric, and
+! therefore require M=(N*(N+1))/2 independent components, which we can arrange
+! into a vector of this size. The utility routines tNN_to_M do this; tM_to_NN
+! do the opposite. tN_to_M put the outer-product of an N-vector into the
+! corresponding M-vector.
+!
+! The filtering is preceded by a decomposition of the M components of the
+! aspect tensor, at each grid point, into M distinct line-second-moments
+! and the line-generators they each act along, at every grid point. And
+! since, in the general case, the aspect tensor is no longer needed once
+! the line filter specifications have been determined, it ic convenient to
+! over-write the old aspect tensor components with the new line-second-
+! moments ("spread**2"). In other word, we can express the needed action
+! as a formal "transform" (and invert it if ever needed, to recover the
+! original aspect tensor). The basic decomposition of the aspect tensor
+! into its spread**2 components and line generators is done, at a single
+! grid point using subroutine triad (2D), hexad (3D), decad (4D). Working
+! this into "transform" for a single point, is done in tritform, hextform,
+! dectform, and their respective inverse transforms in tritformi, hextfotmi,
+! dectformi. In the case of the 3D hexad method, although there are 6 active
+! line filters at any given point, each of those lines is associated with
+! one of the 7 different "colors" (our term for the nonnull Galois field
+! elements) no two of these colors in a given hexad are the same. The
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+use jp_pkind, only: spi,sp,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: T,F,u0,u1,u3,u4,u5,pi2
+implicit none
+private
+public:: t22_to_3,t2_to_3,t3_to_22,t33_to_6,t3_to_6,t6_to_33,&
+ t44_to_10,t4_to_10,t10_to_44, &
+ finmomtab,inimomtab, &
+ tritform,tritformi,triad,gettrilu,querytcol, &
+ hextform,hextformi,hexad,gethexlu,queryhcol, &
+ dectform,dectformi,decad,getdeclu,querydcol, &
+ hstform,hstformi,blinfil,dibeta,dibetat
+integer(spi),dimension(2,0:2):: i2pair
+integer(spi),dimension(2,6) :: i3pair
+integer(spi),dimension(2,10) :: i4pair
+data i2pair/1,1, 2,2, 1,2/
+data i3pair/1,1, 2,2, 3,3, 2,3, 3,1, 1,2/
+data i4pair/1,1, 2,2, 3,3, 4,4, 1,2, 1,3, 1,4, 3,4, 2,4, 2,3/
+
+interface t22_to_3; module procedure i22_to_3, r22_to_3; end interface
+interface t2_to_3; module procedure i2_to_3, r2_to_3; end interface
+interface t3_to_22; module procedure i3_to_22, r3_to_22; end interface
+interface t33_to_6; module procedure i33_to_6, r33_to_6; end interface
+interface t3_to_6; module procedure i3_to_6, r3_to_6; end interface
+interface t6_to_33; module procedure i6_to_33, r6_to_33; end interface
+interface t44_to_10; module procedure i44_to_10,r44_to_10; end interface
+interface t4_to_10; module procedure i4_to_10, r4_to_10; end interface
+interface t10_to_44; module procedure i10_to_44,r10_to_44; end interface
+!---
+interface finmomtab; module procedure finmomtab; end interface
+interface inimomtab; module procedure inimomtab; end interface
+interface tritform; module procedure tritforms,tritform; end interface
+interface tritformi; module procedure tritformi; end interface
+interface triad; module procedure triad; end interface
+interface gettrilu; module procedure gettrilu; end interface
+interface querytcol; module procedure querytcol; end interface
+interface hextform; module procedure hextforms,hextform; end interface
+interface hextformi; module procedure hextformi; end interface
+interface hexad; module procedure hexad; end interface
+interface gethexlu; module procedure gethexlu; end interface
+interface queryhcol; module procedure queryhcol; end interface
+interface dectform; module procedure dectforms,dectform; end interface
+interface dectformi; module procedure dectformi; end interface
+interface decad; module procedure decad; end interface
+interface getdeclu; module procedure getdeclu; end interface
+interface querydcol; module procedure querydcol; end interface
+!---
+interface standardizeb;module procedure standardizeb; end interface
+interface hstform; module procedure hstform; end interface
+interface hstformi; module procedure hstformi; end interface
+interface blinfil; module procedure blinfil; end interface
+interface dibeta
+ module procedure dibeta1,dibeta2,dibeta3,dibeta4, dibetax3,dibetax4, &
+ vdibeta1,vdibeta2,vdibeta3,vdibeta4, vdibetax3,vdibetax4
+end interface
+interface dibetat
+ module procedure dibeta1t,dibeta2t,dibeta3t,dibeta4t,dibetax3t, dibetax4t, &
+ vdibeta1t,vdibeta2t,vdibeta3t,vdibeta4t,vdibetax3t,vdibetax4t
+end interface
+
+contains
+
+!==============================================================================
+subroutine i22_to_3(i22,i3)! [t22_to_3]
+!==============================================================================
+use jp_pkind, only: spi
+implicit none
+integer(spi),dimension(2,2),intent(in ):: i22
+integer(spi),dimension(0:2),intent(out):: i3
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=0,2; i3(L)=i22(i2pair(1,L),i2pair(2,L)); enddo
+end subroutine i22_to_3
+!==============================================================================
+subroutine r22_to_3(r22,r3)! [t22_to_3]
+!==============================================================================
+use jp_pkind, only: spi,dp
+implicit none
+real(dp),dimension(2,2),intent(in ):: r22
+real(dp),dimension(0:2),intent(out):: r3
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=0,2; r3(L)=r22(i2pair(1,L),i2pair(2,L)); enddo
+end subroutine r22_to_3
+
+!==============================================================================
+subroutine i2_to_3(i2,i3)! [t2_to_3]
+!==============================================================================
+use jp_pkind, only: spi
+use jp_pmat4, only: outer_product
+implicit none
+integer(spi),dimension(2),intent(in ):: i2
+integer(spi),dimension(3),intent(out):: i3
+!------------------------------------------------------------------------------
+call t22_to_3(outer_product(i2,i2),i3)
+end subroutine i2_to_3
+!==============================================================================
+subroutine r2_to_3(r2,r3)! [t2_to_3]
+!==============================================================================
+use jp_pkind, only: dp
+use jp_pmat4, only: outer_product
+implicit none
+real(dp),dimension(2),intent(in ):: r2
+real(dp),dimension(3),intent(out):: r3
+!------------------------------------------------------------------------------
+call t22_to_3(outer_product(r2,r2),r3)
+end subroutine r2_to_3
+
+!==============================================================================
+subroutine i3_to_22(i3,i22)! [t3_to_22]
+!==============================================================================
+use jp_pkind, only: spi
+implicit none
+integer(spi),dimension(0:2),intent(in ):: i3
+integer(spi),dimension(2,2),intent(out):: i22
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=0,2
+ i22(i2pair(1,L),i2pair(2,L))=i3(L)
+ i22(i2pair(2,L),i2pair(1,L))=i3(L)
+enddo
+end subroutine i3_to_22
+!==============================================================================
+subroutine r3_to_22(r3,r22)! [t3_to_22]
+!==============================================================================
+use jp_pkind, only: spi,dp
+implicit none
+real(dp),dimension(0:2),intent(in ):: r3
+real(dp),dimension(2,2),intent(out):: r22
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=0,2
+ r22(i2pair(1,L),i2pair(2,L))=r3(L)
+ r22(i2pair(2,L),i2pair(1,L))=r3(L)
+enddo
+end subroutine r3_to_22
+
+!==============================================================================
+subroutine i33_to_6(i33,i6)! [t33_to_6]
+!==============================================================================
+use jp_pkind, only: spi
+implicit none
+integer(spi),dimension(3,3),intent(in ):: i33
+integer(spi),dimension(6) ,intent(out):: i6
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=1,6; i6(L)=i33(i3pair(1,L),i3pair(2,L)); enddo
+end subroutine i33_to_6
+!==============================================================================
+subroutine r33_to_6(r33,r6)! [t33_to_6]
+!==============================================================================
+use jp_pkind, only: spi,dp
+implicit none
+real(dp),dimension(3,3),intent(in ):: r33
+real(dp),dimension(6) ,intent(out):: r6
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=1,6; r6(L)=r33(i3pair(1,L),i3pair(2,L)); enddo
+end subroutine r33_to_6
+
+!==============================================================================
+subroutine i3_to_6(i3,i6)! [t3_to_6]
+!==============================================================================
+use jp_pkind, only: spi
+use jp_pmat4, only: outer_product
+implicit none
+integer(spi),dimension(3),intent(in ):: i3
+integer(spi),dimension(6),intent(out):: i6
+!------------------------------------------------------------------------------
+call t33_to_6(outer_product(i3,i3),i6)
+end subroutine i3_to_6
+!==============================================================================
+subroutine r3_to_6(r3,r6)! [t3_to_6]
+!==============================================================================
+use jp_pkind, only: dp
+use jp_pmat4, only: outer_product
+implicit none
+real(dp),dimension(3),intent(in ):: r3
+real(dp),dimension(6),intent(out):: r6
+!------------------------------------------------------------------------------
+call t33_to_6(outer_product(r3,r3),r6)
+end subroutine r3_to_6
+
+!==============================================================================
+subroutine i6_to_33(i6,i33)! [t6_to_33]
+!==============================================================================
+use jp_pkind, only: spi
+implicit none
+integer(spi),dimension(6), intent(in ):: i6
+integer(spi),dimension(3,3),intent(out):: i33
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=1,6
+ i33(i3pair(1,L),i3pair(2,L))=i6(L)
+ i33(i3pair(2,L),i3pair(1,L))=i6(L)
+enddo
+end subroutine i6_to_33
+!==============================================================================
+subroutine r6_to_33(r6,r33)! [t6_to_33]
+!==============================================================================
+use jp_pkind, only: spi,dp
+implicit none
+real(dp),dimension(6), intent(in ):: r6
+real(dp),dimension(3,3),intent(out):: r33
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=1,6
+ r33(i3pair(1,L),i3pair(2,L))=r6(L)
+ r33(i3pair(2,L),i3pair(1,L))=r6(L)
+enddo
+end subroutine r6_to_33
+
+!==============================================================================
+subroutine i44_to_10(i44,i10)! [t44_to_10]
+!==============================================================================
+use jp_pkind, only: spi
+implicit none
+integer(spi),dimension(4,4),intent(in ):: i44
+integer(spi),dimension(10) ,intent(out):: i10
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=1,10; i10(L)=i44(i4pair(1,L),i4pair(2,L)); enddo
+end subroutine i44_to_10
+!==============================================================================
+subroutine r44_to_10(r44,r10)! [t44_to_10]
+!==============================================================================
+use jp_pkind, only: spi,dp
+implicit none
+real(dp),dimension(4,4),intent(in ):: r44
+real(dp),dimension(10) ,intent(out):: r10
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=1,10; r10(L)=r44(i4pair(1,L),i4pair(2,L)); enddo
+end subroutine r44_to_10
+
+!==============================================================================
+subroutine i4_to_10(i4,i10)! [t4_to_10]
+!==============================================================================
+use jp_pkind, only: spi
+use jp_pmat4, only: outer_product
+implicit none
+integer(spi),dimension(4), intent(in ):: i4
+integer(spi),dimension(10),intent(out):: i10
+!------------------------------------------------------------------------------
+call t44_to_10(outer_product(i4,i4),i10)
+end subroutine i4_to_10
+!==============================================================================
+subroutine r4_to_10(r4,r10)! [t4_to_10]
+!==============================================================================
+use jp_pkind, only: dp
+use jp_pmat4, only: outer_product
+implicit none
+real(dp),dimension(4), intent(in ):: r4
+real(dp),dimension(10),intent(out):: r10
+!------------------------------------------------------------------------------
+call t44_to_10(outer_product(r4,r4),r10)
+end subroutine r4_to_10
+
+!==============================================================================
+subroutine i10_to_44(i10,i44)! [t10_to_44]
+!==============================================================================
+use jp_pkind, only: spi
+implicit none
+integer(spi),dimension(10), intent(in ):: i10
+integer(spi),dimension(4,4),intent(out):: i44
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=1,10
+ i44(i4pair(1,L),i4pair(2,L))=i10(L)
+ i44(i4pair(2,L),i4pair(1,L))=i10(L)
+enddo
+end subroutine i10_to_44
+!==============================================================================
+subroutine r10_to_44(r10,r44)! [t10_to_44]
+!==============================================================================
+use jp_pkind, only: spi,dp
+implicit none
+real(dp),dimension(10), intent(in ):: r10
+real(dp),dimension(4,4),intent(out):: r44
+!------------------------------------------------------------------------------
+integer(spi):: L
+!==============================================================================
+do L=1,10
+ r44(i4pair(1,L),i4pair(2,L))=r10(L)
+ r44(i4pair(2,L),i4pair(1,L))=r10(L)
+enddo
+end subroutine r10_to_44
+
+!--
+
+!================================================================== [finmomtab]
+subroutine finmomtab
+!==============================================================================
+! Finalize the moments table for dibeta filter applications.
+! Deallocate the space reserved for moment tables and reset p and nh to their
+! zero defaults.
+!==============================================================================
+use jp_pbfil2, only: p,nh,bnorm,bsprds
+implicit none
+p=0; nh=0
+if(allocated(bnorm))deallocate(bnorm)
+if(allocated(bsprds))deallocate(bsprds)
+end subroutine finmomtab
+
+!================================================================== [inimomtab]
+subroutine inimomtab(p_prescribe,nh_prescribe,ff)
+!==============================================================================
+! Initialize the moments table for dibeta filter applications.
+! For the given beta function exponent index, p, and nh half-spans, initialize
+! table of the normalizing coefficients, bnorm, and spread**2s, bsprds.
+! The calculation involves computing the continuum approximations, m0 and m2,
+! to the 0th and 2nd moments, and using the Euler-Maclaurin expansions
+! for the correction terms hm0 and hm2 so that the final corrected moments
+! cm0 and cm2 for each integer halfwidth up to nh .
+!==============================================================================
+use jp_pkind, only: spi,dp
+use jp_pietc, only: u0,u1,u2
+use jp_pbfil2, only: p,nh,bnorm,bsprds
+implicit none
+integer(spi),intent(in ):: p_prescribe,nh_prescribe
+logical, intent(out):: ff
+!------------------------------------------------------------------------------
+integer(spi),parameter :: nk0=2,nk2=nk0+1,np=6,np2p3=np*2+3
+real(dp),dimension(-1:np2p3) :: ffac
+real(dp) :: x,xx,m0,m2,hm0,hm2,cm0,cm2
+integer(spi),dimension(0:nk0,np):: n0pk
+integer(spi),dimension(0:nk2,np):: n2pk
+integer(spi) :: h,i,k,mk0,mk2,p2,p2m1,p2p1,p2p3
+data n0pk/ &
+ -1, 0, 0, &
+ -1, 0, 0, &
+ -5, 14, 0, &
+ -63, 240, 0, &
+ -1575, 6930, -2640, &
+ -68409, 327600, -216216/
+data n2pk/ &
+ 1, -5, 0, 0, &
+ 5, -21, 0, 0, &
+ 63, -285, 126, 0, &
+ 1575, -7623, 5280, 0, &
+ 68409, -348075, 306306, -34320, &
+ 4729725,-24969285, 25552800, -5405400/
+!==============================================================================
+call finmomtab ! Table arrays bnorm and bsprds must start off deallocated
+ff=(p_prescribe<1 .or. p_prescribe>np)
+if(ff)then
+ print'(" In inimomtab; prescribed exponent p out of bounds")'
+ return
+endif
+ff=(nh_prescribe<2 .or. nh_prescribe>1000)
+if(ff)then
+ print'(" In inimomtab; prescribed table size nh out of bounds")'
+ return
+endif
+p =p_prescribe
+nh=nh_prescribe
+allocate(bnorm(nh),bsprds(nh))
+! set up the ffac tables (double-factorial function)
+p2=p*2; p2m1=p2-1; p2p1=p2+1; p2p3=p2+3
+ffac(-1)=u1
+ffac(0)=u1
+do i=1,np2p3
+ ffac(i)=i*ffac(i-2)
+enddo
+mk0=(p-1)/2
+mk2=mk0+1
+do h=1,nh
+ x=h
+ xx=x*x
+ m0=u2*ffac(p2)*x/ffac(p2p1)
+ m2=u2*ffac(p2)*x**3/ffac(p2p3)
+ hm0=u0
+ do k=0,mk0
+ hm0=hm0+n0pk(k,p)*xx**k
+ enddo
+ hm2=u0
+ do k=0,mk2
+ hm2=hm2+n2pk(k,p)*xx**k
+ enddo
+ cm0=m0+hm0/(ffac(p2p1)*x**p2m1)
+ cm2=m2+hm2/(ffac(p2p3)*x**p2m1)
+ bnorm(h)=u1/cm0
+ bsprds(h)=cm2/cm0
+enddo
+end subroutine inimomtab
+
+!================================================================== [tritform]
+subroutine tritforms(lx,mx, ly,my, aspects, dixs,diys, ff)
+!=============================================================================
+! Perform direct Triad and hs transforms in a proper subdomain
+! domains extents in x, y, are lx:mx, ly:my
+! aspects: upon input, these are the 3-vectors of grid-relative aspect tensor
+! upon output, these are the 3 active line-filter half-spans.
+! dixs: x-component of each of the 6 active line generators
+! diys: y-component
+! ff: Logical failure flag, output .true. when failure occurs.
+! Note that the integer arrays, doxs, diys, are 1-byte integers.
+!==============================================================================
+
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+implicit none
+integer(spi), intent(in ):: lx,mx,ly,my
+real(dp), dimension(3,lx:mx,ly:my),intent(inout):: aspects
+integer(fpi),dimension(lx:mx,ly:my,3),intent( out):: dixs,diys
+logical, intent( out):: ff
+!-----------------------------------------------------------------------------
+integer(spi) :: ix,iy
+integer(fpi),dimension(2,3):: ltri
+!=============================================================================
+do iy=ly,my
+ do ix=lx,mx
+ call tritform(aspects(:,ix,iy),ltri,ff)
+ if(ff)then
+ print'(" Failure in tritform at ix,iy=",2i5)',ix,iy
+ return
+ endif
+ dixs(ix,iy,:)=ltri(1,:)
+ diys(ix,iy,:)=ltri(2,:)
+ enddo
+enddo
+end subroutine tritforms
+
+!=================================================================== [tritform]
+subroutine tritform(aspect ,ltri, ff)
+!==============================================================================
+! Perform the direct Triad and hs transform.
+! Take a 3-vector representation of the aspect tensor and
+! transform it to the vector of half-spans for the beta line filter
+! and 1-byte-integer line generators.
+! aspect: input as aspect tensor components, output as spread**2
+! ltri : three active line generators in ascending color order
+! ff : logical failure flag.
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+implicit none
+real(dp),dimension(3), intent(inout):: aspect
+integer(fpi),dimension(2,3),intent( out):: ltri
+logical, intent( out):: ff
+!------------------------------------------------------------------------------
+real(dp), dimension( 3):: wtri
+integer(fpi),dimension(2,3):: ltri3
+integer(spi) :: i
+!==============================================================================
+call triad(aspect, ltri3,wtri,ff)
+if(ff)then
+ print'(" In tritform; triad failed; check aspect tensor")'
+ return
+endif
+ltri=ltri3
+aspect=wtri
+do i=1,3
+ call hstform(aspect(i),ff)
+ if(ff)then
+ print'(" In tritform; hstform failed at i=",i2)',i
+ print'(" Check that inimomtab has been called to initialize exponent")'
+ print'(" p, table size, nh, and the moment tables for line filters")'
+ return
+ endif
+enddo
+end subroutine tritform
+
+!================================================================== [tritformi]
+subroutine tritformi(aspect ,ltri, ff)
+!==============================================================================
+! Perform the inverse hs and triad transform.
+! Take a 3-vector of the active spreads**2,
+! and their line generators, and return the implied
+! aspect tensor in the same 3-vector that contained the half-spans
+! aspect: input as half-spans; output as aspect tensor components
+! ltri : corresponding successive line generators (using 1-byte integers)
+! ff : logical failure flag.
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+use jp_pmat4, only: outer_product
+implicit none
+real(dp),dimension(3),intent(inout) :: aspect
+integer(fpi),dimension(2,3),intent(in ):: ltri
+logical, intent( out):: ff
+!------------------------------------------------------------------------------
+real(dp),dimension(2,2):: a22
+real(dp),dimension(2) :: vec
+integer(spi) :: i
+!==============================================================================
+a22=u0
+do i=1,3
+ vec=ltri(:,i)
+ call hstformi(aspect(i),ff)
+ if(ff)then
+ print'(" In tritformi; hstformi failed at i=",i2)',i
+ print'(" Check that inimomtab has been called to initialize exponent")'
+ print'(" p, table size, nh, and the moment tables for line filters")'
+ return
+ endif
+ a22=a22+outer_product(vec,vec)*aspect(i)
+enddo
+call t22_to_3(a22,aspect)
+end subroutine tritformi
+
+!===================================================================== [triad]
+subroutine triad(aspect,ltri,wtri,ff)
+!=============================================================================
+! A version of the Triad iterative algorithm for resolving a given aspect
+! tensor, A, rearranged as the 3-vector,
+! Aspect = (/A_11, A_22, A_12/)
+! onto a bisis of generator directions, the integer 2-vectors ltri, together
+! with their corresponding aspect projections, or "weights", wtri.
+!
+! Aspect: The given aspect tensor in the form of a 3-vector (see above)
+! Ltri: The three integer 2-vectors whose members define a triad
+! and whose outer-products imply basis 3-vectors into which the aspect
+! is resolved. This matrix of 3-vectors is denoted Lu, but only its
+! inverse, Lui, is needed in this routine.
+! wtri: Real nonnegative weights (projected aspect) corresponding to ltri.
+! ff : Failure flag, raised on output only when iterations exceed limit.
+!=============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pmat4, only: outer_product
+implicit none
+real(dp), dimension(3), intent(in ):: aspect
+integer(fpi),dimension(2,0:2),intent(out):: ltri
+real(dp), dimension(0:2) ,intent(out):: wtri
+logical, intent(out):: ff
+!-----------------------------------------------------------------------------
+integer(spi),parameter :: nit=200
+real(dp), parameter :: bcmins=-1.e-14_dp
+real(dp), dimension(3,0:2):: rlui
+real(dp) :: dwtri
+integer(spi),dimension(-2:2) :: ssigns
+integer(spi),dimension(0:2) :: signs
+integer(fpi),dimension(2,0:2):: defltri ! <- default Ltri
+integer(spi),dimension(3,0:2):: deflui ! <- default Lui
+integer(spi),dimension(3,0:2):: lui
+integer(spi),dimension(3) :: dlui
+integer(spi),dimension(1) :: ii
+integer(spi) :: it,kcol,lcol,mcol
+data ssigns/1,1,-1,1,1/
+data deflui/1, 0,-1, 0, 1,-1, 0, 0, 1/
+data defltri/ 1, 0, 0,1, -1,-1/
+!==============================================================================
+ltri=defltri; lui=deflui
+rlui=lui; wtri=matmul(aspect,rlui)
+do it=1,nit
+ ii=minloc(wtri)-1; kcol=ii(1); dwtri=wtri(kcol)*2; if(dwtri>=bcmins)exit
+ lcol=mod(kcol+1,3); mcol=mod(lcol+1,3); dlui=lui(:,kcol)*2
+ Ltri(:,lcol)=-Ltri(:,Lcol); Ltri(:,kcol)=-Ltri(:,Lcol)-Ltri(:,mcol)
+ signs=ssigns(-kcol:2-kcol)
+ lui=lui+outer_product(dlui,signs)
+ wtri=wtri+signs*dwtri
+enddo
+ff=it>nit
+end subroutine triad
+
+!=================================================================== [gettrilu]
+subroutine gettrilu(ltri,lu)
+!==============================================================================
+use jp_pkind, only: spi; use jp_pkind2, only: fpi
+implicit none
+integer(fpi),dimension(2,0:2),intent(in ):: ltri
+integer(fpi),dimension(2,0:2),intent(out):: lu
+!-----------------------------------------------------------------------------
+integer(spi):: i,L
+!==============================================================================
+do i=0,2; do L=1,2; lu(L,i)=Ltri(i2pair(1,L),i)*Ltri(i2pair(2,L),i);enddo;enddo
+end subroutine gettrilu
+
+!==============================================================================
+subroutine querytcol(vin,tcol)! [querytcol]
+!==============================================================================
+use jp_pkind, only: spi
+implicit none
+integer(spi),dimension(2),intent(in ):: vin
+integer(spi), intent(out):: tcol
+!------------------------------------------------------------------------------
+integer(spi),dimension(3):: tcols
+integer(spi) :: i
+data tcols/0,1,2/
+!==============================================================================
+i=modulo(vin(1),2)+2*modulo(vin(2),2)
+if(i==0)stop 'In querytcol; invalid 2-vector vin has all components even'
+tcol=tcols(i)
+end subroutine querytcol
+
+!=================================================================== [hextform]
+subroutine hextforms(lx,mx,ly,my,lz,mz, aspects, qcols,dixs,diys,dizs, ff)
+!==============================================================================
+! Perform direct hexad and hs transforms in a proper subdomain
+! domains extents in x, y, z, are lx:mx, ly:my, lz:mz
+! aspects: upon input, these are the 6-vectors of grid-relative aspect tensor
+! upon output, these are the six active-line-filter half-spans.
+! qcols: outout as the Galois "colors" of each successive line-filter, listed
+! in ascending order but with zeros at positions 0 and 7 of each list.
+! dixs: x-component of each of the 6 active line generators
+! diys: y-component
+! dizs: z-component
+! ff: Logical failure flag, output .true. when failure occurs.
+! Note that the integer arrays, qcols, doxs, diys, dizs, are 1-byte integers.
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+implicit none
+integer(spi), intent(in ):: lx,mx, &
+ ly,my, &
+ lz,mz
+real(dp), dimension( 6,lx:mx,ly:my,lz:mz),intent(inout):: aspects
+integer(fpi),dimension(0:7,lx:mx,ly:my,lz:mz),intent( out):: qcols
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,6), intent( out):: dixs,diys,dizs
+logical, intent( out):: ff
+!------------------------------------------------------------------------------
+integer(spi) :: ix,iy,iz
+integer(fpi),dimension(3,6):: lhex
+!==============================================================================
+do iz=lz,mz
+ do iy=ly,my
+ do ix=lx,mx
+ call hextform(aspects(:,ix,iy,iz),qcols(:,ix,iy,iz),&
+ lhex,ff)
+ if(ff)then
+ print'(" Failure in hextform at ix,iy,iz=",3i5)',ix,iy,iz
+ return
+ endif
+ dixs(ix,iy,iz,:)=lhex(1,:)
+ diys(ix,iy,iz,:)=lhex(2,:)
+ dizs(ix,iy,iz,:)=lhex(3,:)
+ enddo
+ enddo
+enddo
+end subroutine hextforms
+
+!=================================================================== [hextform]
+subroutine hextform(aspect, qcol,lhex, ff)
+!==============================================================================
+! Perform the direct Hexad and hs transform.
+! Take a 6-vector representation of the aspect tensor and
+! transform it to the vector of half-spans for the dibeta filter,
+! and 1-byte-integer line generators, and color list.
+! aspect: input as aspect tensor components, output as half-spans
+! qcol : output as colors of successive active lines, but with
+! "spare" null elements 0 and 7.
+! lhex : six active line generators in ascending color order
+! ff : logical failure flag.
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+implicit none
+real(dp),dimension(6), intent(inout):: aspect
+integer(fpi),dimension(0:7),intent( out):: qcol
+integer(fpi),dimension(3,6),intent( out):: lhex
+logical, intent( out):: ff
+!------------------------------------------------------------------------------
+real(dp), dimension( 7):: whex7
+integer(fpi),dimension(3,7):: lhex7
+integer(fpi) :: i,j
+!==============================================================================
+call hexad(aspect, lhex7,whex7,ff)
+if(ff)then
+ print'(" In hextform; hexad, failed; check aspect tensor")'
+ return
+endif
+qcol(0)=0; qcol(7)=0
+j=1
+do i=1,7
+ if(sum(abs(lhex7(:,i)))==0)cycle
+ qcol(j)=i
+ lhex(:,j)=lhex7(:,i)
+ aspect(j)=whex7( i)
+ j=j+1_fpi
+enddo
+do i=1,6
+ call hstform(aspect(i),ff)
+ if(ff)then
+ print'(" In hextform; hstform failed at i=",i2)',i
+ print'(" Check that inimomtab has been called to initialize exponent")'
+ print'(" p, table size, nh, and the moment tables for line filters")'
+ return
+ endif
+enddo
+ff=(j/=7)
+if(ff)print'(" In hextform; inconsistent hexad generator set found")'
+end subroutine hextform
+
+!================================================================== [hextformi]
+subroutine hextformi(aspect, qcol,lhex, ff)
+!==============================================================================
+! Perform the inverse hs and hexad transform.
+! Take a 6-vector of the active half-spans, their respective
+! colors, and their line generators, and return the implied
+! aspect tensor in the same 6-vector that contained the spreads**2
+! aspect: input as spreads**2; output as aspect tensor components
+! qcol : colors of successive active hexad members (using 1-byte integers)
+! lhex : corresponding successive line generators (using 1-byte integers)
+! ff : logical failure flag.
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+use jp_pmat4, only: outer_product
+implicit none
+real(dp), dimension( 6),intent(inout):: aspect
+integer(fpi),dimension(0:7),intent(in ):: qcol
+integer(fpi),dimension(3,6),intent(in ):: lhex
+logical, intent( out):: ff
+!------------------------------------------------------------------------------
+real(dp),dimension(3,3):: a33
+real(dp),dimension(3) :: vec
+integer(fpi) :: i,j
+!==============================================================================
+a33=u0
+j=1
+do i=1,7
+ if(qcol(j)/=i)cycle
+ call hstformi(aspect(j),ff)
+ if(ff)then
+ print'(" In hextformi; hstformi failed at i,j=",2i2)',i,j
+ print'(" Check that inimomtab has been called to initialize exponent")'
+ print'(" p, table size, nh, and the moment tables for line filters")'
+ return
+ endif
+ vec=lhex(:,j)
+ a33=a33+outer_product(vec,vec)*aspect(j)
+ j=j+1_fpi
+enddo
+ff=(j/=7)
+if(ff)print'(" In hextformi; Inconsistent qcol")'
+call t33_to_6(a33,aspect)
+end subroutine hextformi
+
+!====================================================================== [hexad]
+subroutine hexad(aspect,lhex7,whex7,ff)
+!==============================================================================
+! A version of the Hexad iterative algorithm for resolving a given aspect
+! tensor, A, rearranged as the 6-vector,
+! Aspect= (/ A_11, A_22, A_33, A_23, A_31, A_12 /)
+! onto a basis of generator directions, the integer 3-vectors lhex7, together
+! with their corresponding aspect projections, or "weights", whex7.
+! Although seven lhex vectors and weights are given (arranged by "colors" 0--6)
+! only six of these -- those that do NOT equal the "color" of the hexad
+! itself --- are nonzero (and are positive when the hexad is correctly
+! resolving the target aspect tensor, Aspect). The style of this algorithm
+! is as close as possible to the the description in documentation "Note 7".
+!
+! Aspect: the given aspect tensor in the form of a 6-vector (see above).
+! Lhex7: The seven integer 3-vectors whose 6 non-null members define a Hexad
+! and whose outer-products imply basis 6-vectors into which the aspect
+! is resolved. This matrix of 6-vectors is denoted Lu, but only its
+! inverse, Lui, is needed in this routine. These seven 3-vectors are
+! arranged in decreasing order of "cardinality",
+! meaning that the cardinal
+! directions' colors define the first three vectors, the next three have
+! two odd components, and the seventh has all odd components.
+! whex7: Seven real nonnegative weights (projected aspect)
+! corresponding to lhex
+! (zero value in the case of the null vector of lhex7)
+! ff : failure flag, raised only when the iterations exceed their limit.
+! The algorithm here benefits from using the symmetry of the Fano plane
+! and related GF(8) nonnull elements which, arranged cyclically, imply that
+! the Jth "line" comprises points j+line(0), j+line(1), j+line(2), where
+! Line = (/ 1, 2, 4/) and j is taken modulo 7.
+! Note: the "K-set" of 3 members of the Lhex (indexed hcol+6, hcol+5, hcol+3)
+! or equivalently, hcol-line(0),hcol-line(1),hclo-line(2),
+! where arithmetic is modulo-7, are sufficient to form a "basis" from which
+! the other ("L-set") nonnull members of Lhex are implied. To make the
+! iterations efficient, we can iterate just this K-set, because the changes
+! made to the effective projection operator, Lui, are, by the Woodbury
+! formula, of rank-1 at each iteration, and the whex components change by
+! a corresponding pattern of increments that do not need us to find the full
+! set of Lhex, nor the explicit Lu, each iteration.
+! Note that some integer arrays use 1-byte integer type to save space.
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+use jp_pmat4, only: outer_product
+implicit none
+real(dp), dimension(6), intent(in ):: aspect
+integer(fpi),dimension(3,7), intent(out):: lhex7
+real(dp), dimension(7), intent(out):: whex7
+logical, intent(out):: ff
+!------------------------------------------------------------------------------
+integer(spi),parameter :: nit=200
+real(dp), parameter :: bcmins=-1.e-14_dp
+real(dp), dimension(6,0:6) :: rlui
+real(dp), dimension(0:6) :: whex
+real(dp) :: dwhex
+integer(spi),dimension(0:6) :: signs
+integer(fpi),dimension(3,0:6) :: deflhex
+integer(spi),dimension(6,0:6) :: deflui
+integer(spi),dimension(-6:6) :: sstriad
+integer(spi),dimension(6) :: dlui,ttriad
+integer(fpi),dimension(3,0:2) :: Kset
+integer(fpi),dimension(3,3,6) :: mmats
+integer(spi),dimension(0:2) :: Line
+integer(spi),dimension(1) :: ii
+integer(fpi),dimension(3,0:6) :: lhex
+integer(spi),dimension(6,0:6) :: lui
+integer(spi),dimension(0:6) :: jcol
+integer(spi) :: hcol
+integer(spi) :: i,ip,it,j,kcol,dcol,L
+data deflhex/0,0,0, 1,-1,0, 0,1,-1, 0,0,1, -1,0,1, 0,1,0, 1,0,0/
+data deflui/ 6*0, 0, 0, 0, 0, 0,-1, 0, 0, 0,-1, 0, 0, 0, 0, 1, 1, 1, 0, &
+ 0, 0, 0, 0,-1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1/
+data Mmats/1, 1,-1, 1, 0, 0, 1, 0,-1, -1, 1, 0, -1, 1, 1, 0, 1, 0, &
+ 0,-1, 1, 1,-1, 0, 1, 0, 0, 0, 0, 1, 0,-1, 1, 1,-1, 1, &
+ -1, 0, 1, 0, 0, 1, -1, 1, 0, 0, 1, 0, 1, 0,-1, 0, 1,-1/
+data ttriad/5,3,3,6,5,6/
+data sstriad/-1,-1, 1,-1, 1, 1, 1,-1,-1, 1,-1, 1, 1/
+data Line/1,2,4/
+data jcol/7,4,6,3,5,2,1/
+!==============================================================================
+lhex=deflhex; lui=deflui; hcol=0
+rlui=lui; whex=matmul(aspect,rlui)
+do i=0,2; Kset(:,i)=Lhex(:,modulo(hcol-line(i),7)); enddo
+do it=1,nit
+ ii=minloc(whex)-1; kcol=ii(1); dwhex=whex(kcol); if(dwhex>=bcmins)exit
+ dcol=modulo(kcol-hcol,7); hcol=kcol; L=modulo(hcol+ttriad(dcol),7)
+ Kset=matmul(Kset,Mmats(:,:,dcol))
+ dlui=lui(:,hcol)
+ signs=sstriad(-L:6-L)
+ lui =lui+outer_product(dlui,signs)
+ whex=whex+signs*dwhex
+enddo
+ff=it>nit; if(ff)return
+do i=0,2; ip=modulo(i+1,3)
+ lhex(:,modulo(hcol-line(i),7))=Kset(:,i)
+ lhex(:,modulo(hcol+line(i),7))=Kset(:,i)-Kset(:,ip)
+enddo
+lhex(:,kcol)=0
+lhex7=0
+whex7=u0
+do i=0,6
+ j=jcol(i)
+ lhex7(:,j)=lhex(:,i)
+ whex7( j)=whex( i)
+enddo
+
+end subroutine hexad
+
+!=================================================================== [gethexlu]
+subroutine gethexlu(lhex,lu)
+!==============================================================================
+use jp_pkind, only: spi; use jp_pkind2, only: fpi
+implicit none
+integer(fpi),dimension(3,0:6),intent(in ):: lhex
+integer(fpi),dimension(6,0:6),intent(out):: lu
+!------------------------------------------------------------------------------
+integer(spi):: i,L
+!==============================================================================
+do i=0,6; do L=1,6; lu(L,i)=Lhex(i3pair(1,L),i)*Lhex(i3pair(2,L),i);enddo;enddo
+end subroutine gethexlu
+
+!==============================================================================
+subroutine queryhcol(vin,hcol)! [queryhcol]
+!==============================================================================
+use jp_pkind, only: spi
+implicit none
+integer(spi),dimension(3),intent(in ):: vin
+integer(spi), intent(out):: hcol
+!------------------------------------------------------------------------------
+integer(spi),dimension(7):: hcols
+integer(spi) :: i
+data hcols/6,5,1,3,4,2,0/
+!==============================================================================
+i=modulo(vin(1),2)+2*modulo(vin(2),2)+4*modulo(vin(3),2)
+if(i==0)stop 'In queryhcol; invalid 3-vector Vin has all components even'
+hcol=hcols(i)
+end subroutine queryhcol
+
+!=================================================================== [dectform]
+subroutine dectforms(lx,mx,ly,my,lz,mz,lw,mw,aspects,qcols, &
+ dixs,diys,dizs,diws, ff)
+!==============================================================================
+! Perform direct Decad and ha transforms in a proper subdomain
+! domains extents in x, y, z, w, are lx:mx, ly:my, lz:mz, lw:mw
+! aspects: upon input, these are the 10-vectors of grid-relative aspect tensor
+! upon output, these are the ten active-line-filter half-spans.
+! qcols: outout as the Galois "colors" of each successive line-filter, listed
+! in ascending order, with zeros at positions 0 and 11 of each list.
+! dixs: x-component of each of the 6 active line generators
+! diys: y-component
+! dizs: z-component
+! diws: w-component
+! ff: Logical failure flag, output .true. when failure occurs.
+! Note that the integer arrays, qcols, doxs, diys, dizs, diws,
+! are 1-byte integers.
+!
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+implicit none
+integer(spi), intent(in ):: lx,mx,&
+ ly,my,&
+ lz,mz,&
+ lw,mw
+real(dp),dimension(10,lx:mx,ly:my,lz:mz,lw:mw), intent(inout):: aspects
+integer(fpi),dimension(0:11,lx:mx,ly:my,lz:mz,lw:mw),intent( out):: qcols
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw,10), intent( out):: dixs,&
+ diys,&
+ dizs,&
+ diws
+logical, intent( out):: ff
+!------------------------------------------------------------------------------
+integer(spi) :: ix,iy,iz,iw
+integer(fpi),dimension(4,10):: ldec
+!==============================================================================
+do iw=lw,mw
+ do iz=lz,mz
+ do iy=ly,my
+ do ix=lx,mx
+ call dectform(aspects(:,ix,iy,iz,iw),qcols(0:11,ix,iy,iz,iw),&
+ ldec,ff)
+ if(ff)then
+ print'(" Failure in dectform at ix,iy,iz,iw=",4i5)',&
+ ix,iy,iz,iw
+ return
+ endif
+ dixs(ix,iy,iz,iw,:)=ldec(1,:)
+ diys(ix,iy,iz,iw,:)=ldec(2,:)
+ dizs(ix,iy,iz,iw,:)=ldec(3,:)
+ diws(ix,iy,iz,iw,:)=ldec(4,:)
+ enddo
+ enddo
+ enddo
+enddo
+end subroutine dectforms
+
+!=================================================================== [dectform]
+subroutine dectform(aspect, qcol,ldec, ff)
+!==============================================================================
+! Perform the direct Decad and hs transform.
+! Take a 10-vector representation of the aspect tensor and
+! transform it to the vector of half-spans
+! and 1-byte-integer line generators, and color list.
+! aspect: input as aspect tensor components, output as spread**2
+! qcol : output as colors of successive active lines, but with
+! "spare" null elements 0 and 11.
+! ldec : ten active line generators in ascending color order
+! ff : logical failure flag.
+!=============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+implicit none
+real(dp),dimension(10), intent(inout):: aspect
+integer(fpi),dimension(0:11),intent( out):: qcol
+integer(fpi),dimension(4,10),intent( out):: ldec
+logical, intent( out):: ff
+!-----------------------------------------------------------------------------
+real(dp), dimension( 15):: wdec15
+integer(fpi),dimension(4,15):: ldec15
+integer(fpi) :: i,j
+!=============================================================================
+call decad(aspect, ldec15,wdec15,ff)
+if(ff)then
+ print'(" In dectform; decad, failed; check aspect tensor")'
+ return
+endif
+qcol(0)=0; qcol(11)=0
+j=1
+do i=1,15
+ if(sum(abs(ldec15(:,i)))==0)cycle
+ qcol(j)=i
+ ldec(:,j)=ldec15(:,i)
+ aspect(j)=wdec15( i)
+ j=j+1_fpi
+enddo
+do i=1,10
+ call hstform(aspect(i),ff)
+ if(ff)then
+ print'(" In dectform; hstform failed at i=",i2)',i
+ print'(" Check that inimomtab has been called to initialize exponent")'
+ print'(" p, table size, nh, and the moment tables for line filters")'
+ return
+ endif
+enddo
+
+ff=(j/=11)
+if(ff)print'(" In dectform; inconsistent decad generator set found")'
+end subroutine dectform
+
+!================================================================= [dectformi]
+subroutine dectformi(aspect, qcol,ldec, ff)
+!=============================================================================
+! Perform the inverse hs and decad transform.
+! Take a 10-vector of the active half-spans, their respective
+! colors, and their line generators, and return the implied
+! aspect tensor in the same 10-vector that contained the spreads**2
+! aspect: input as spreads**2; output as aspect tensor components
+! qcol : colors of successive active decad members (using 1-byte integers)
+! ldec : corresponding successive line generators (using 1-byte integers)
+! ff : logical failure flag.
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+use jp_pmat4, only: outer_product
+implicit none
+real(dp), dimension( 10),intent(inout):: aspect
+integer(fpi),dimension(0:11),intent(in ):: qcol
+integer(fpi),dimension(4,10),intent(in ):: ldec
+logical, intent( out):: ff
+!------------------------------------------------------------------------------
+real(dp),dimension(4,4):: a44
+real(dp),dimension(4) :: vec
+integer(spi) :: i,j
+!==============================================================================
+a44=u0
+j=1
+do i=1,15
+ if(qcol(j)/=i)cycle
+ call hstformi(aspect(j),ff)
+ if(ff)then
+ print'(" In dectformi; hstformi failed at i,j=",2i3)',i,j
+ print'(" Check that inimomtab has been called to initialize exponent")'
+ print'(" p, table size, nh, and the moment tables for line filters")'
+ return
+ endif
+ vec=ldec(:,j)
+ a44=a44+outer_product(vec,vec)*aspect(j)
+ j=j+1
+enddo
+ff=(j/=11)
+if(ff)then
+ print'(" In dectformi; Inconsistent qcol")'
+ return
+endif
+call t44_to_10(a44,aspect)
+end subroutine dectformi
+
+!====================================================================== [decad]
+subroutine decad(aspect,ldec15,wdec15,ff)
+!==============================================================================
+! This version is derived from $HOMES/on500/decadf.f90
+! In this version ALWAYS start from the default decad
+! Also, rearrange the 10 active line directions and weights
+! into arrays of 15, ordered according the colors of the fundamental
+! 3*3*3*3 cube's surface generators' degrees of "cardinality". By this
+! we mean that the colors of (1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1)
+! come first, followed by the colors of (1,1,0,0), (1,0,1,0), (1,0,0,1),
+! (0,1,1,0), (0,1,0,1), (0,0,1,1), followed by the colors of (1,1,1,0),
+! (1,1,0,1), (1,0,1,1), (0,1,1,1), and followed finally by the color
+! of the "least cardinal" (or "most diagonal") type of element, (1,1,1,1).
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+use jp_pbfil2,only: dec0,dodec0t,umat10,umat12,umats,nei,dcol10,dcol12,&
+ nei0a,jcora,nei0b,jcorb,nei17,nei22,nei33,nei38, tcors,&
+ kcor10a5,kcor10b1,kcor10b2,kcor12b0, &
+ kcor17c0,kcor22c0,kcor33c0,kcor38c0,kcor44c0,kcor51c0,kcor53c0,kcor58c0,&
+ twt10a5,twt10b1,twt10b2,twt12c0,qwt10a,qwt10b,qwt10c,qwt10d,qwt10e, &
+ qwt12a,qwt12b0,tperms,perm10,perm12,perms
+use jp_pmat, only: inv
+use jp_pmat4, only: outer_product,det
+implicit none
+real(dp),dimension(10), intent(in ):: aspect
+integer(fpi),dimension(4,15),intent(out):: ldec15
+real(dp), dimension( 15),intent(out):: wdec15
+logical, intent(out):: ff
+!------------------------------------------------------------------------------
+integer(spi), parameter :: nit=40
+real(dp),parameter :: bcmins=-1.e-14_dp
+real(dp),dimension(10,0:9) :: rlui
+real(dp),dimension(0:9) :: awdec,xwdec,newwdec,wdec
+real(dp) :: dwdec
+integer(spi) :: ktyp,dcol ! Redundant?
+integer(spi),dimension(0:9) :: palet !
+integer(spi),dimension(4,0:9) :: eldec !
+integer(spi),dimension(10,0:9) :: lu,lui
+integer(fpi),dimension(4,0:9) :: defeldec
+integer(spi),dimension(4,0:9) :: neweldec
+integer(spi),dimension(0:9) :: defpalet
+integer(spi),dimension(1) :: ii
+integer(spi),dimension(4,4) :: tcor
+integer(spi) :: i,it,j,k,newktyp,newdcol,abscol,&
+ jcol,kcor,jcor
+integer(spi),dimension(4,0:3) :: newbase
+integer(spi),dimension(0:9) :: perm,qwt,tperm
+integer(spi),dimension(0:14) :: icol15
+data icol15/1,2,3,4,5,8,10,12,6,9,11,14,15,13,7/
+data defeldec/ &
+ 0, 0, 1, 0, 0,-1, 0, 0, 1, 0, 0, 0, -1, 0,-1,-1, 0, 1, 0, 1, &
+ 0, 0, 0,-1, -1, 0,-1, 0, 1, 1, 1, 1, -1,-1, 0,-1, 1, 0, 0, 1/
+data defpalet/ 2, 1, 0,13, 9, 3, 8,12, 7,14/
+!==============================================================================
+eldec=defeldec; palet=defpalet; ktyp=4; dcol=4
+do j=0,9; call t4_to_10(eldec(:,j),lu(:,j)); enddo
+lui=transpose(lu)
+call inv(lui,ff)
+if(ff)then
+ print'(" In decad, at A; lu cannot be inverted")'
+ return
+endif
+rlui=lui
+wdec=matmul(aspect,rlui)
+do it=1,nit
+ ii=minloc(wdec)-1; k=ii(1); dwdec=wdec(k);
+ if(dwdec>=bcmins)exit
+!-- The following is translated from the "x" block of old tdecadf:
+ newktyp=nei(k,ktyp)
+ if(ktyp<12)then
+ abscol=modulo(dcol+dcol10(k,ktyp),15)! Anticipated uncorrected abs col
+ newbase(:,:)=matmul(eldec(:,0:3),umat10(:,:,k,ktyp))
+ else
+ if(k<4)then
+ abscol=modulo(dcol+dcol12(k,ktyp),15)
+ newbase(:,:)=matmul(eldec(:,0:3),umat12(:,:,k,ktyp))/2
+ else
+ abscol=dcol
+ newbase(:,:)=matmul(eldec(:,0:3),umats(:,:,k))/2
+ endif
+ endif
+ jcol=0
+ jcor=0
+ if(newktyp==11)then
+ jcol=abscol/3
+ if(jcol>0)then
+ jcor=6+jcol
+ endif
+ abscol=modulo(abscol,3)
+ elseif(newktyp>=44)then
+ jcol=abscol/5
+ if(jcol>0)then
+ select case(ktyp)
+ case(0:3)
+ newktyp=nei0a(jcol,ktyp)
+ jcor=jcora(jcol,ktyp)
+ case(4:9)
+ newktyp=nei0b(jcol,k,ktyp)
+ jcor=jcorb(jcol,k,ktyp)
+ case(17); newktyp=nei17(jcol); jcor=10+jcol
+ case(22); newktyp=nei22(jcol); jcor=10+jcol
+ case(33); newktyp=nei33(jcol); jcor=10+jcol
+ case(38); newktyp=nei38(jcol); jcor=10+jcol
+ case(44); jcor=10+jcol
+ case(51); jcor=10+jcol
+ case(53); jcor=10+jcol
+ case(58); jcor=10+jcol
+ case default
+ print'(" In decad. Unrecognized ktyp=",i10)',ktyp
+ ff=.true.
+ return
+ end select
+ endif
+ abscol=modulo(abscol,5)
+ if(ktyp<12)then
+ newdcol=modulo(abscol-dcol10(k,ktyp),15)
+ else
+ if(k<4)then
+ newdcol=modulo(abscol-dcol12(k,ktyp),15)
+ else
+ newdcol=dcol
+ endif
+ endif
+ endif
+ if(jcor /= 0)then
+ tcor=tcors(:,:,jcor)
+ newbase=matmul(newbase(:,:),tcor)/2
+ endif
+
+ if(ktyp<12)then
+ perm=perm10(:,k,ktyp)
+ select case(ktyp)
+ case(0:3)
+ if(k==5)then
+ kcor=kcor10a5(jcol,ktyp)
+ qwt=twt10a5(:,kcor)
+ else
+ qwt=qwt10a(:,k)
+ endif
+ case(4:7)
+ if(k==1)then
+ kcor=kcor10b1(jcol,ktyp)
+ qwt=twt10b1(:,kcor)
+ elseif(k==2)then
+ kcor=kcor10b2(jcol,ktyp)
+ qwt=twt10b2(:,kcor)
+ else
+ qwt=qwt10b(:,k)
+ endif
+ case(8:9)
+ if(k==1)then
+ kcor=kcor10b1(jcol,ktyp)
+ qwt=twt10b1(:,kcor)
+ elseif(k==2)then
+ kcor=kcor10b2(jcol,ktyp)
+ qwt=twt10b2(:,kcor)
+ else
+ qwt=qwt10c(:,k)
+ endif
+ case(10)
+ qwt=qwt10d(:,k)
+ case(11)
+ qwt=qwt10e(:,k)
+ end select
+ else
+ if(k==0)then
+ perm=perm12(:,k,ktyp)
+ kcor=kcor12b0(ktyp)
+ select case(ktyp)
+ case(17); kcor=kcor17c0(jcol); qwt=twt12c0(:,kcor)
+ case(22); kcor=kcor22c0(jcol); qwt=twt12c0(:,kcor)
+ case(33); kcor=kcor33c0(jcol); qwt=twt12c0(:,kcor)
+ case(38); kcor=kcor38c0(jcol); qwt=twt12c0(:,kcor)
+ case(44); kcor=kcor44c0(jcol); qwt=twt12c0(:,kcor)
+ case(51); kcor=kcor51c0(jcol); qwt=twt12c0(:,kcor)
+ case(53); kcor=kcor53c0(jcol); qwt=twt12c0(:,kcor)
+ case(58); kcor=kcor58c0(jcol); qwt=twt12c0(:,kcor)
+ case default
+ qwt=qwt12b0(:,kcor)
+ end select
+ elseif(k<4)then
+ perm=perm12(:,k,ktyp)
+ qwt=qwt12a(:,k)
+ else
+ perm=perms(:,k)
+ qwt=qwt12a(:,k)
+ endif
+ endif
+ if(jcor/=0)then
+ do i=0,9
+ tperm(i)=tperms(perm(i),jcor)
+ enddo
+ perm=tperm
+ endif
+ call standardizeb(newbase(:,:),FF)
+ if(FF)then
+ print'(" In decad, at B; failure of subr. standardizedb")'
+ return
+ endif
+
+!--------
+ awdec=wdec-qwt*dwdec
+ do i=0,9
+ newwdec(perm(i))=awdec(i)
+ enddo
+ if(newktyp<12)then
+ neweldec=matmul(newbase,dec0)
+ else
+ neweldec=matmul(newbase,dodec0t)/2
+ endif
+ do j=0,9
+ call t4_to_10(neweldec(:,j),lu(:,j))
+ enddo
+ lui=transpose(lu)
+ call inv(lui,ff)
+ if(ff)then
+ print'(" In decad, at C; lu cannot be inverted")'
+ return
+ endif
+ rlui=lui
+ xwdec=matmul(aspect,rlui)
+! if(maxval(abs(xwdec-newwdec))>.001)read(*,*)
+ eldec=neweldec
+ ktyp=newktyp
+ dcol=abscol
+ wdec=xwdec
+enddo
+if(it>nit)then
+ ff=.true.
+ print '(" in decad, at D; failure of decad iterations to converge")'
+ return
+endif
+do j=0,9
+ call querydcol(eldec(:,j),palet(j))
+enddo
+print'(" departing decad having used it = ",i5," iterations.")',it
+! Insert the decad into its proper color slots in order of decreasing
+! "cardinality:"
+wdec15=u0
+ldec15=0
+do i=0,9
+ j=icol15(palet(i))
+! ldec15(:,j)=int(eldec(:,i),kind(fpi))
+ ldec15(:,j)=int(eldec(:,i),fpi)
+ wdec15( j)= wdec( i)
+enddo
+end subroutine decad
+
+!=================================================================== [getdeclu]
+subroutine getdeclu(ldec,lu)
+!==============================================================================
+use jp_pkind, only: spi; use jp_pkind2, only: fpi
+implicit none
+integer(spi),dimension( 4,0:14),intent(in ):: ldec
+integer(spi),dimension(10,0:14),intent(out):: lu
+!------------------------------------------------------------------------------
+integer(spi):: i,L
+!==============================================================================
+do i=0,14;do L=1,10;lu(L,i)=Ldec(i4pair(1,L),i)*Ldec(i4pair(2,L),i);enddo;enddo
+end subroutine getdeclu
+
+!==============================================================================
+subroutine querydcol(vin,dcol)! [querydcol]
+!==============================================================================
+use jp_pkind, only: spi; use jp_pkind2, only: fpi
+implicit none
+integer(spi),dimension(4),intent(in ):: vin
+integer(spi), intent(out):: dcol
+!------------------------------------------------------------------------------
+integer(spi),dimension(15):: dcols
+integer(spi),dimension(4) :: bbbb
+integer(spi) :: i
+data dcols/ 0, 1, 4, 2, 8, 5,10, 3,14, 9, 7, 6,13,11,12/
+data bbbb/1,2,4,8/
+!==============================================================================
+i=dot_product(bbbb,modulo(vin,2))
+if(i==0)stop 'In querydcol; invalid 4-vector Vin has all components even'
+dcol=dcols(i)
+end subroutine querydcol
+
+!=============================================================== [standardizeb]
+subroutine standardizeb(bases,FF)
+!==============================================================================
+! Standardize 4*4 bases vectors by making sure the first nonzero component
+! of the first column is positive in the standardized version.
+! If the first column is null, raise the (logical) failure flag, FF.
+!==============================================================================
+use jp_pkind, only: spi
+implicit none
+integer(spi),dimension(4,4),intent(inout):: bases
+logical, intent( out):: FF
+integer(spi) :: i,b
+!==============================================================================
+FF=.false.
+do i=1,4
+ b=bases(i,1)
+ if(b==0)cycle
+ if(b<0)bases=-bases
+ return
+enddo
+print'(" WARNING! In subroutine standardizeb, first column is null:")'
+FF=.true.
+end subroutine standardizeb
+
+!==================================================================== [hstform]
+subroutine hstform(hs,ff)!
+!==============================================================================
+! Perform the "hspan transform". For a given spread**2, replace it with the
+! corresponding effective half-span corresponding to beta filters of the
+! already-initialized exponent p. Generally, hs>=1, lies between consecutive
+! integers, h, h+1 <=nh (nh is also already given in jp_pbfil2.mod). The linear
+! interpolation weights at h and h+1 for this target, applied to the
+! "interpolation" of the two standardized p-exponent beta distributions of
+! half-spans h and h+1 will also be standardized (sum of gridded responses = 1)
+! and will possess exactly the prescribed spread**2, the input hs.
+! This transform is obviously invertible (see subr. hstformi).
+! But if the given hs does not fit within the range of the
+! table, bsprds, return a raised failure flag, ff.
+!==============================================================================
+use jp_pkind, only: spi,dp
+use jp_pietc, only: u0
+use jp_pbfil2,only: nh,bsprds
+implicit none
+real(dp),intent(inout):: hs
+logical, intent( out):: ff
+!------------------------------------------------------------------------------
+integer(spi):: h
+!==============================================================================
+ff=hs= hs)then
+ hs=h-(bsprds(h)-hs)/(bsprds(h)-bsprds(h-1))
+ return
+ endif
+enddo
+ff=.true.
+end subroutine hstform
+
+!=================================================================== [hstformi]
+subroutine hstformi(hs,ff)
+!==============================================================================
+! Perform the "inverse hspan transform" (inverse function of hstform) so that
+! an effective p-exponent beta filter half-span, hs, is replaced by the second
+! moment (spread**2) of the dibeta filter this half-span implies.
+! If the given half-span is not accommodated by the prepared table, bsprds, of
+! module jp_pbfil3, return a raised failure flag, ff.
+!==============================================================================
+use jp_pkind, only: spi,dp
+use jp_pietc, only: u1
+use jp_pbfil2,only: nh,bsprds
+implicit none
+real(dp),intent(inout):: hs
+logical, intent( out):: ff
+!------------------------------------------------------------------------------
+real(dp) :: w
+integer(spi):: h
+!==============================================================================
+h=1+int(hs)
+ff=(h<2 .or. h>nh)
+if(ff)then
+ print'(" In hstformi; hs out of bounds")'
+ return
+endif
+! Linearly interpolate the spread**2 from the table bsprds:
+w=h-hs
+hs=w*bsprds(h-1)+(u1-w)*bsprds(h)
+end subroutine hstformi
+
+!==================================================================== [blinfil]
+subroutine blinfil(nfil,hspan, h,fil,ff)
+!==============================================================================
+! Find the discrete halfspan h and the filtering weights, fil(0:h), of
+! the normalized dibeta filter of formal real half-span, hspan. The dibeta
+! filter is just a weighted combination of two consecutive-halfspan
+! beta filters such that the spread**2 of the dibeta is the weighted
+! intermediate of the spreads**2 of the pair of beta filters from which it
+! is composed.
+!
+! p: beta filter exponent index
+! nh: size of the table listing the normalization factors and spreads**2
+! bnorm: table of normalization factors for beta filters of integer halfspan
+! bsprds: table of squared-spreads of the beta filters
+! hspan: formal real half-span of the dibeta filter
+! fil: a real array, [0:nh], sufficient to accommodate one half of the
+! symmetric discrete dibeta filter.
+! ff: logical failure flag raised when hspan lies outside the table range.
+!==============================================================================
+use jp_pkind, only: spi,dp
+use jp_pietc, only: u1
+use jp_pbfil2,only: p,nh,bnorm
+implicit none
+integer(spi), intent(in ):: nfil
+real(dp), intent(in ):: hspan
+integer(spi), intent(out):: h
+real(dp),dimension(0:nfil),intent(out):: fil
+logical, intent(out):: ff
+!------------------------------------------------------------------------------
+real(dp) :: wh,whp,z
+integer(spi):: hp,i
+!==============================================================================
+h=int(hspan); hp=h+1; ff=h<1 .or. hp>nh .or. hp>nfil; if(ff)return
+whp =(hspan-h)*bnorm(hp)! linear interpolation weight at hp=h+1
+wh=(hp-hspan)*bnorm(h)! linear interpolation weight at h
+! start with the contribution of the filter of formal halfspan h+1:
+do i=0,h; z=i; z=(z/hp)**2; fil(i)= whp*(u1-z)**p; enddo
+! add the contribution of the filter of formal halfspan h:
+do i=0,h-1; z=i; z=(z/h)**2; fil(i)=fil(i)+wh*(u1-z)**p; enddo
+end subroutine blinfil
+
+!-- The following routines share the interface, dibeta:
+!===================================================================== [dibeta]
+subroutine dibeta1(kx,lx,mx,nx, nfil,dixs,hss,a,ff,ix)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx, nfil
+integer(fpi),dimension(lx:mx),intent(in ):: dixs
+real(dp), dimension(lx:mx),intent(in ):: hss
+real(dp), dimension(kx:nx),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil):: fil
+real(dp),dimension(kx:nx) :: b
+real(dp) :: fili
+integer(spi) :: h,i,dix,dixi
+!==============================================================================
+b=u0
+do ix=lx,mx
+ dix=dixs(ix)
+ if(dix==0)then;b(ix)=a(ix)
+ else
+ call blinfil(nfil,hss(ix),h,fil,ff); if(ff)return
+ b(ix)=fil(0)*a(ix)
+ do i=1,h
+ fili=fil(i); dixi=dix*i
+ b(ix)=b(ix)+fili*(a(ix+dixi)+a(ix-dixi))
+ enddo
+ endif
+enddo
+a=b
+end subroutine dibeta1
+!===================================================================== [dibeta]
+subroutine dibeta2(kx,lx,mx,nx, ky,ly,my,ny, nfil, &
+ dixs,diys,hss, a, ff,ix,iy)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my),intent(in ):: dixs,diys
+real(dp), dimension(lx:mx,ly:my),intent(in ):: hss
+real(dp), dimension(kx:nx,ky:ny),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(kx:nx,ky:ny):: b
+real(dp) :: fili
+integer(spi) :: h,i,dix,diy,dixi,diyi
+!==============================================================================
+b=u0
+do iy=ly,my; do ix=lx,mx
+ dix=dixs(ix,iy); diy=diys(ix,iy)
+ if(abs(dix)+abs(diy)==0)then;b(ix,iy)=a(ix,iy)
+ else
+ call blinfil(nfil,hss(ix,iy),h,fil,ff); if(ff)return
+ b(ix,iy)=fil(0)*a(ix,iy)
+ do i=1,h
+ fili=fil(i); dixi=dix*i; diyi=diy*i
+ b(ix,iy)=b(ix,iy)+fili*(a(ix+dixi,iy+diyi)+a(ix-dixi,iy-diyi))
+ enddo
+ endif
+enddo; enddo
+a=b
+end subroutine dibeta2
+!===================================================================== [dibeta]
+subroutine dibeta3(kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, nfil, &
+ dixs,diys,dizs,hss, a, ff,ix,iy,iz)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ kz,lz,mz,nz,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my,lz:mz),intent(in ):: dixs,diys,dizs
+real(dp), dimension(lx:mx,ly:my,lz:mz),intent(in ):: hss
+real(dp), dimension(kx:nx,ky:ny,kz:nz),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(kx:nx,ky:ny,kz:nz):: b
+real(dp) :: fili
+integer(spi) :: h,i, &
+ dix,diy,diz, &
+ dixi,diyi,dizi
+!==============================================================================
+b=u0
+do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ dix=dixs(ix,iy,iz); diy=diys(ix,iy,iz); diz=dizs(ix,iy,iz)
+ if(abs(dix)+abs(diy)+abs(diz)==0)then;b(ix,iy,iz)=a(ix,iy,iz)
+ else
+ call blinfil(nfil,hss(ix,iy,iz),h,fil,ff); if(ff)return
+ b(ix,iy,iz)=fil(0)*a(ix,iy,iz)
+ do i=1,h
+ fili=fil(i); dixi=dix*i; diyi=diy*i; dizi=diz*i
+ b(ix,iy,iz)=b(ix,iy,iz)+fili* &
+ (a(ix+dixi,iy+diyi,iz+dizi)&
+ +a(ix-dixi,iy-diyi,iz-dizi))
+ enddo
+ endif
+enddo; enddo; enddo
+a=b
+end subroutine dibeta3
+!===================================================================== [dibeta]
+subroutine dibeta4(kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, kw,lw,mw,nw, &
+ nfil, dixs,diys,dizs,diws,hss, a, ff,ix,iy,iz,iw)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ kz,lz,mz,nz,&
+ kw,lw,mw,nw,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw),intent(in ):: dixs,diys,&
+ dizs,diws
+real(dp), dimension(lx:mx,ly:my,lz:mz,lw:mw),intent(in ):: hss
+real(dp), dimension(kx:nx,ky:ny,kz:nz,kw:nw),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz,iw
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(kx:nx,ky:ny,kz:nz,kw:nw):: b
+real(dp) :: fili
+integer(spi) :: h,i, &
+ dix,diy,diz,diw, &
+ dixi,diyi,dizi,diwi
+!==============================================================================
+b=u0
+do iw=lw,mw; do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ dix=dixs(ix,iy,iz,iw);diy=diys(ix,iy,iz,iw)
+ diz=dizs(ix,iy,iz,iw);diw=diws(ix,iy,iz,iw)
+ if(abs(dix)+abs(diy)+abs(diz)+abs(diw)==0)then;b(ix,iy,iz,iw)=a(ix,iy,iz,iw)
+ else
+ call blinfil(nfil,hss(ix,iy,iz,iw),h,fil,ff); if(ff)return
+ b(ix,iy,iz,iw)=fil(0)*a(ix,iy,iz,iw)
+ do i=1,h
+ fili=fil(i); dixi=dix*i; diyi=diy*i; dizi=diz*i; diwi=diw*i
+ b(ix,iy,iz,iw)=b(ix,iy,iz,iw)+fili* &
+ (a(ix+dixi,iy+diyi,iz+dizi,iw+diwi)&
+ +a(ix-dixi,iy-diyi,iz-dizi,iw-diwi))
+ enddo
+ endif
+enddo; enddo; enddo; enddo
+a=b
+end subroutine dibeta4
+
+!===================================================================== [dibeta]
+subroutine dibetax3(kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, icol,nfil,&
+ qcols,dixs,diys,dizs, jcol,hss,a, ff,ix,iy,iz)
+!=============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx, &
+ ky,ly,my,ny, &
+ kz,lz,mz,nz, &
+ icol,nfil
+integer(fpi),dimension(0:7,lx:mx,ly:my,lz:mz),intent(in ):: qcols
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,6), intent(in ):: dixs,diys,dizs
+
+integer(fpi),dimension(lx:mx,ly:my,lz:mz), intent(inout):: jcol
+real(dp),dimension(6,lx:mx,ly:my,lz:mz), intent(in ):: hss
+real(dp),dimension(kx:nx,ky:ny,kz:nz), intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(kx:nx,ky:ny,kz:nz):: b
+real(dp) :: fili,hs
+integer(spi) :: h,i, &
+ dix,diy,diz, &
+ dixi,diyi,dizi
+integer(fpi) :: j
+!==============================================================================
+b=u0
+if(icol==1)jcol=1
+do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ j=jcol(ix,iy,iz)
+ if(icol/=qcols(j,ix,iy,iz))then
+ b(ix,iy,iz)=a(ix,iy,iz)
+ cycle
+ else
+ jcol(ix,iy,iz)=j+1_fpi
+ dix=dixs(ix,iy,iz,j); diy=diys(ix,iy,iz,j); diz=dizs(ix,iy,iz,j)
+ hs=hss(j,ix,iy,iz)
+ call blinfil(nfil,hs,h,fil,ff); if(ff)return
+ b(ix,iy,iz)=fil(0)*a(ix,iy,iz)
+ do i=1,h
+ fili=fil(i); dixi=dix*i; diyi=diy*i; dizi=diz*i
+ b(ix,iy,iz)=b(ix,iy,iz)+fili* &
+ (a(ix+dixi,iy+diyi,iz+dizi)&
+ +a(ix-dixi,iy-diyi,iz-dizi))
+ enddo
+ endif
+enddo; enddo; enddo
+a=b
+end subroutine dibetax3
+!===================================================================== [dibeta]
+subroutine dibetax4(kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, kw,lw,mw,nw, &
+ icol,nfil,&
+ qcols,dixs,diys,dizs,diws, jcol,hss,a, ff,ix,iy,iz,iw)
+!=============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx, &
+ ky,ly,my,ny, &
+ kz,lz,mz,nz, &
+ kw,lw,mw,nw, &
+ icol,nfil
+integer(fpi),dimension(0:11,lx:mx,ly:my,lz:mz,lw:mw),&
+ intent(in ):: qcols
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw,10),&
+ intent(in ):: dixs,diys,&
+ dizs,diws
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw),intent(inout):: jcol
+real(dp),dimension(10,lx:mx,ly:my,lz:mz,lw:mw), intent(in ):: hss
+real(dp),dimension(kx:nx,ky:ny,kz:nz,kw:nw), intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz,iw
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(kx:nx,ky:ny,kz:nz,kw:nw):: b
+real(dp) :: fili,hs
+integer(spi) :: h,i, &
+ dix,diy,diz,diw, &
+ dixi,diyi,dizi,diwi
+integer(fpi) :: j
+!==============================================================================
+b=u0
+if(icol==1)jcol=1
+do iw=lw,mw; do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ j=jcol(ix,iy,iz,iw)
+ if(icol/=qcols(j,ix,iy,iz,iw))then
+ b(ix,iy,iz,iw)=a(ix,iy,iz,iw)
+ cycle
+ else
+ jcol(ix,iy,iz,iw)=j+1_fpi
+ dix=dixs(ix,iy,iz,iw,j); diy=diys(ix,iy,iz,iw,j)
+ diz=dizs(ix,iy,iz,iw,j); diw=diws(ix,iy,iz,iw,j)
+ hs=hss(j,ix,iy,iz,iw)
+ call blinfil(nfil,hs,h,fil,ff); if(ff)return
+ b(ix,iy,iz,iw)=fil(0)*a(ix,iy,iz,iw)
+ do i=1,h
+ fili=fil(i); dixi=dix*i; diyi=diy*i; dizi=diz*i; diwi=diw*i
+ b(ix,iy,iz,iw)=b(ix,iy,iz,iw)+fili* &
+ (a(ix+dixi,iy+diyi,iz+dizi,iw+diwi)&
+ +a(ix-dixi,iy-diyi,iz-dizi,iw-diwi))
+ enddo
+ endif
+enddo; enddo; enddo; enddo
+a=b
+end subroutine dibetax4
+
+!===================================================================== [dibeta]
+subroutine vdibeta1(nv,kx,lx,mx,nx, nfil,dixs,hss,a,ff,ix)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv,kx,lx,mx,nx, nfil
+integer(fpi),dimension(lx:mx),intent(in ):: dixs
+real(dp), dimension(lx:mx),intent(in ):: hss
+real(dp), dimension(nv,kx:nx),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx) :: b
+real(dp) :: fili
+integer(spi) :: h,i,dix,dixi
+!==============================================================================
+b=u0
+do ix=lx,mx
+ dix=dixs(ix)
+ if(dix==0)then; b(:,ix)=a(:,ix)
+ else
+ call blinfil(nfil,hss(ix),h,fil,ff); if(ff)return
+ b(:,ix)=fil(0)*a(:,ix)
+ do i=1,h
+ fili=fil(i); dixi=dix*i
+ b(:,ix)=b(:,ix)+fili*(a(:,ix+dixi)+a(:,ix-dixi))
+ enddo
+ endif
+enddo
+a=b
+end subroutine vdibeta1
+!===================================================================== [dibeta]
+subroutine vdibeta2(nv, kx,lx,mx,nx, ky,ly,my,ny, nfil, &
+ dixs,diys,hss, a, ff,ix,iy)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv, &
+ kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my),intent(in ):: dixs,diys
+real(dp), dimension(lx:mx,ly:my),intent(in ):: hss
+real(dp), dimension(nv,kx:nx,ky:ny),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx,ky:ny):: b
+real(dp) :: fili
+integer(spi) :: h,i,dix,diy,dixi,diyi
+!==============================================================================
+b=u0
+do iy=ly,my; do ix=lx,mx
+ dix=dixs(ix,iy); diy=diys(ix,iy)
+ if(abs(dix)+abs(diy)==0)then;b(:,ix,iy)=a(:,ix,iy)
+ else
+ call blinfil(nfil,hss(ix,iy),h,fil,ff); if(ff)return
+ b(:,ix,iy)=fil(0)*a(:,ix,iy)
+ do i=1,h
+ fili=fil(i); dixi=dix*i; diyi=diy*i
+ b(:,ix,iy)=b(:,ix,iy)+fili* &
+ (a(:,ix+dixi,iy+diyi)+a(:,ix-dixi,iy-diyi))
+ enddo
+ endif
+enddo; enddo
+a=b
+end subroutine vdibeta2
+!===================================================================== [dibeta]
+subroutine vdibeta3(nv, kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, nfil, &
+ dixs,diys,dizs,hss, a, ff,ix,iy,iz)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv, &
+ kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ kz,lz,mz,nz,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my,lz:mz),intent(in ):: dixs,diys,dizs
+real(dp), dimension(lx:mx,ly:my,lz:mz),intent(in ):: hss
+real(dp), dimension(nv,kx:nx,ky:ny,kz:nz),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz):: b
+real(dp) :: fili
+integer(spi) :: h,i, &
+ dix,diy,diz, &
+ dixi,diyi,dizi
+!==============================================================================
+b=u0
+do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ dix=dixs(ix,iy,iz); diy=diys(ix,iy,iz); diz=dizs(ix,iy,iz)
+ if(abs(dix)+abs(diy)+abs(diz)==0)then;b(:,ix,iy,iz)=a(:,ix,iy,iz)
+ else
+ call blinfil(nfil,hss(ix,iy,iz),h,fil,ff); if(ff)return
+ b(:,ix,iy,iz)=fil(0)*a(:,ix,iy,iz)
+ do i=1,h
+ fili=fil(i); dixi=dix*i; diyi=diy*i; dizi=diz*i
+ b(:,ix,iy,iz)=b(:,ix,iy,iz)+fili* &
+ (a(:,ix+dixi,iy+diyi,iz+dizi)&
+ +a(:,ix-dixi,iy-diyi,iz-dizi))
+ enddo
+ endif
+enddo; enddo; enddo
+a=b
+end subroutine vdibeta3
+!===================================================================== [dibeta]
+subroutine vdibeta4(nv, kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, kw,lw,mw,nw, &
+ nfil, dixs,diys,dizs,diws,hss, a, ff,ix,iy,iz,iw)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv, &
+ kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ kz,lz,mz,nz,&
+ kw,lw,mw,nw,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw),intent(in ):: dixs,diys,&
+ dizs,diws
+real(dp), dimension(lx:mx,ly:my,lz:mz,lw:mw),intent(in ):: hss
+real(dp), dimension(nv,kx:nx,ky:ny,kz:nz,kw:nw),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz,iw
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz,kw:nw):: b
+real(dp) :: fili
+integer(spi) :: h,i, &
+ dix,diy,diz,diw, &
+ dixi,diyi,dizi,diwi
+!==============================================================================
+b=u0
+do iw=lw,mw; do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ dix=dixs(ix,iy,iz,iw);diy=diys(ix,iy,iz,iw)
+ diz=dizs(ix,iy,iz,iw);diw=diws(ix,iy,iz,iw)
+ if(abs(dix)+abs(diy)+abs(diz)+abs(diw)==0)then
+ b(:,ix,iy,iz,iw)=a(:,ix,iy,iz,iw)
+ else
+ call blinfil(nfil,hss(ix,iy,iz,iw),h,fil,ff); if(ff)return
+ b(:,ix,iy,iz,iw)=fil(0)*a(:,ix,iy,iz,iw)
+ do i=1,h
+ fili=fil(i); dixi=dix*i; diyi=diy*i; dizi=diz*i; diwi=diw*i
+ b(:,ix,iy,iz,iw)=b(:,ix,iy,iz,iw)+fili* &
+ (a(:,ix+dixi,iy+diyi,iz+dizi,iw+diwi)&
+ +a(:,ix-dixi,iy-diyi,iz-dizi,iw-diwi))
+ enddo
+ endif
+enddo; enddo; enddo; enddo
+a=b
+end subroutine vdibeta4
+
+!===================================================================== [dibeta]
+subroutine vdibetax3(nv,kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, icol,nfil,&
+ qcols,dixs,diys,dizs, jcol,hss,a, ff,ix,iy,iz)
+!=============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv, &
+ kx,lx,mx,nx, &
+ ky,ly,my,ny, &
+ kz,lz,mz,nz, &
+ icol,nfil
+integer(fpi),dimension(0:7,lx:mx,ly:my,lz:mz),intent(in ):: qcols
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,6), intent(in ):: dixs,diys,dizs
+integer(fpi),dimension(lx:mx,ly:my,lz:mz), intent(inout):: jcol
+real(dp),dimension(6,lx:mx,ly:my,lz:mz), intent(in ):: hss
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz), intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz):: b
+real(dp) :: fili,hs
+integer(spi) :: h,i, &
+ dix,diy,diz, &
+ dixi,diyi,dizi
+integer(fpi) :: j
+!==============================================================================
+b=u0
+if(icol==1)jcol=1
+do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ j=jcol(ix,iy,iz)
+ if(icol/=qcols(j,ix,iy,iz))then
+ b(:,ix,iy,iz)=a(:,ix,iy,iz)
+ cycle
+ else
+ jcol(ix,iy,iz)=j+1_fpi
+ dix=dixs(ix,iy,iz,j); diy=diys(ix,iy,iz,j); diz=dizs(ix,iy,iz,j)
+ hs=hss(j,ix,iy,iz)
+ call blinfil(nfil,hs,h,fil,ff); if(ff)return
+ b(:,ix,iy,iz)=fil(0)*a(:,ix,iy,iz)
+ do i=1,h
+ fili=fil(i); dixi=dix*i; diyi=diy*i; dizi=diz*i
+ b(:,ix,iy,iz)=b(:,ix,iy,iz)+fili* &
+ (a(:,ix+dixi,iy+diyi,iz+dizi)&
+ +a(:,ix-dixi,iy-diyi,iz-dizi))
+ enddo
+ endif
+enddo; enddo; enddo
+a=b
+end subroutine vdibetax3
+!===================================================================== [dibeta]
+subroutine vdibetax4(nv,kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, kw,lw,mw,nw, &
+ icol,nfil,&
+ qcols,dixs,diys,dizs,diws, jcol,hss,a, ff,ix,iy,iz,iw)
+!=============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv, &
+ kx,lx,mx,nx, &
+ ky,ly,my,ny, &
+ kz,lz,mz,nz, &
+ kw,lw,mw,nw, &
+ icol,nfil
+integer(fpi),dimension(0:11,lx:mx,ly:my,lz:mz,lw:mw),&
+ intent(in ):: qcols
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw,10),&
+ intent(in ):: dixs,diys,&
+ dizs,diws
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw),intent(inout):: jcol
+real(dp),dimension(10,lx:mx,ly:my,lz:mz,lw:mw), intent(in ):: hss
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz,kw:nw), intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz,iw
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz,kw:nw):: b
+real(dp) :: fili,hs
+integer(spi) :: h,i, &
+ dix,diy,diz,diw, &
+ dixi,diyi,dizi,diwi
+integer(fpi) :: j
+!==============================================================================
+b=u0
+if(icol==1)jcol=1
+do iw=lw,mw; do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ j=jcol(ix,iy,iz,iw)
+ if(icol/=qcols(j,ix,iy,iz,iw))then
+ b(:,ix,iy,iz,iw)=a(:,ix,iy,iz,iw)
+ cycle
+ else
+ jcol(ix,iy,iz,iw)=j+1_fpi
+ dix=dixs(ix,iy,iz,iw,j); diy=diys(ix,iy,iz,iw,j)
+ diz=dizs(ix,iy,iz,iw,j); diw=diws(ix,iy,iz,iw,j)
+ hs=hss(j,ix,iy,iz,iw)
+ call blinfil(nfil,hs,h,fil,ff); if(ff)return
+ b(:,ix,iy,iz,iw)=fil(0)*a(:,ix,iy,iz,iw)
+ do i=1,h
+ fili=fil(i); dixi=dix*i; diyi=diy*i; dizi=diz*i; diwi=diw*i
+ b(:,ix,iy,iz,iw)=b(:,ix,iy,iz,iw)+fili* &
+ (a(:,ix+dixi,iy+diyi,iz+dizi,iw+diwi)&
+ +a(:,ix-dixi,iy-diyi,iz-dizi,iw-diwi))
+ enddo
+ endif
+enddo; enddo; enddo; enddo
+a=b
+end subroutine vdibetax4
+
+!--- The following routine share the interface, dibetat:
+
+!==================================================================== [dibetat]
+subroutine dibeta1t(kx,lx,mx,nx, nfil, dixs,hss, a, ff,ix)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx,nfil
+integer(fpi),dimension(lx:mx),intent(in ):: dixs
+real(dp), dimension(lx:mx),intent(in ):: hss
+real(dp), dimension(kx:nx),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil):: fil
+real(dp),dimension(kx:nx) :: b
+real(dp) :: filiat,at
+integer(spi) :: h,i,dix,dixi
+!==============================================================================
+b=u0
+do ix=lx,mx
+ at=a(ix)
+ dix=dixs(ix)
+ if(dix==0)then;b(ix)=b(ix)+at
+ else
+ call blinfil(nfil,hss(ix),h,fil,ff); if(ff)return
+ b(ix)=b(ix)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i
+ b(ix+dixi)=b(ix+dixi)+filiat
+ b(ix-dixi)=b(ix-dixi)+filiat
+ enddo
+ endif
+enddo
+a=b
+end subroutine dibeta1t
+!==================================================================== [dibetat]
+subroutine dibeta2t(kx,lx,mx,nx, ky,ly,my,ny, &
+ nfil, dixs,diys,hss, a, ff,ix,iy)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my),intent(in ):: dixs,diys
+real(dp), dimension(lx:mx,ly:my),intent(in ):: hss
+real(dp), dimension(kx:nx,ky:ny),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(kx:nx,ky:ny):: b
+real(dp) :: filiat,at
+integer(spi) :: h,i,dix,diy,dixi,diyi
+!==============================================================================
+b=u0
+do iy=ly,my; do ix=lx,mx
+ at=a(ix,iy)
+ dix=dixs(ix,iy); diy=diys(ix,iy)
+ if(abs(dix)+abs(diy)==0)then;b(ix,iy)=b(ix,iy)+at
+ else
+ call blinfil(nfil,hss(ix,iy),h,fil,ff); if(ff)return
+ b(ix,iy)=b(ix,iy)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i; diyi=diy*i
+ b(ix+dixi,iy+diyi)=b(ix+dixi,iy+diyi)+filiat
+ b(ix-dixi,iy-diyi)=b(ix-dixi,iy-diyi)+filiat
+ enddo
+ endif
+enddo; enddo
+a=b
+end subroutine dibeta2t
+!==================================================================== [dibetat]
+subroutine dibeta3t(kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, &
+ nfil, dixs,diys,dizs,hss, a, ff,ix,iy,iz)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ kz,lz,mz,nz,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my,lz:mz),intent(in ):: dixs,diys,dizs
+real(dp), dimension(lx:mx,ly:my,lz:mz),intent(in ):: hss
+real(dp), dimension(kx:nx,ky:ny,kz:nz),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(kx:nx,ky:ny,kz:nz):: b
+real(dp) :: filiat,at
+integer(spi) :: h,i, &
+ dix,diy,diz,&
+ dixi,diyi,dizi
+!==============================================================================
+b=u0
+do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ at=a(ix,iy,iz)
+ dix=dixs(ix,iy,iz); diy=diys(ix,iy,iz); diz=dizs(ix,iy,iz)
+ if(abs(dix)+abs(diy)+abs(diz)==0)then;b(ix,iy,iz)=b(ix,iy,iz)+at
+ else
+ call blinfil(nfil,hss(ix,iy,iz),h,fil,ff); if(ff)return
+ b(ix,iy,iz)=b(ix,iy,iz)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i; diyi=diy*i; dizi=diz*i
+ b(ix+dixi,iy+diyi,iz+dizi)=b(ix+dixi,iy+diyi,iz+dizi)+filiat
+ b(ix-dixi,iy-diyi,iz-dizi)=b(ix-dixi,iy-diyi,iz-dizi)+filiat
+ enddo
+ endif
+enddo; enddo; enddo
+a=b
+end subroutine dibeta3t
+
+!==================================================================== [dibetat]
+subroutine dibeta4t(kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, kw,lw,mw,nw, &
+ nfil,dixs,diys,dizs,diws,hss, a,ff,ix,iy,iz,iw)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ kz,lz,mz,nz,&
+ kw,lw,mw,nw,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw),intent(in ):: dixs,diys,&
+ dizs,diws
+real(dp), dimension(lx:mx,ly:my,lz:mz,lw:mw),intent(in ):: hss
+real(dp), dimension(kx:nx,ky:ny,kz:nz,kw:nw),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz,iw
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(kx:nx,ky:ny,kz:nz,kw:nw):: b
+real(dp) :: filiat,at
+integer(spi) :: h,i, &
+ dix,diy,diz,diw, &
+ dixi,diyi,dizi,diwi
+!==============================================================================
+b=u0
+do iw=lw,mw; do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ at=a(ix,iy,iz,iw)
+ dix=dixs(ix,iy,iz,iw); diy=diys(ix,iy,iz,iw)
+ diz=dizs(ix,iy,iz,iw); diw=diws(ix,iy,iz,iw)
+ if(abs(dix)+abs(diy)+abs(diz)+abs(diw)==0)then
+ b(ix,iy,iz,iw)=b(ix,iy,iz,iw)+at
+ else
+ call blinfil(nfil,hss(ix,iy,iz,iw),h,fil,ff); if(ff)return
+ b(ix,iy,iz,iw)=b(ix,iy,iz,iw)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i; diyi=diy*i; dizi=diz*i; diwi=diw*i
+ b(ix+dixi,iy+diyi,iz+dizi,iw+diwi)= &
+ b(ix+dixi,iy+diyi,iz+dizi,iw+diwi)+filiat
+ b(ix-dixi,iy-diyi,iz-dizi,iw-diwi)= &
+ b(ix-dixi,iy-diyi,iz-dizi,iw-diwi)+filiat
+ enddo
+ endif
+enddo; enddo; enddo; enddo
+a=b
+end subroutine dibeta4t
+
+!==================================================================== [dibetat]
+subroutine dibetax3t(kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, icol,nfil,&
+ qcols,dixs,diys,dizs, jcol,hss,a, ff,ix,iy,iz)
+!=============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx, &
+ ky,ly,my,ny, &
+ kz,lz,mz,nz, &
+ icol,nfil
+integer(fpi),dimension(0:7,lx:mx,ly:my,lz:mz),intent(in ):: qcols
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,6), intent(in ):: dixs,diys,dizs
+integer(fpi),dimension(lx:mx,ly:my,lz:mz), intent(inout):: jcol
+real(dp),dimension(6,lx:mx,ly:my,lz:mz), intent(in ):: hss
+real(dp),dimension(kx:nx,ky:ny,kz:nz), intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(kx:nx,ky:ny,kz:nz):: b
+real(dp) :: filiat,hs,at
+integer(spi) :: h,i, &
+ dix,diy,diz, &
+ dixi,diyi,dizi
+integer(fpi) :: j
+!==============================================================================
+b=u0
+if(icol==7)jcol=6
+do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ at=a(ix,iy,iz)
+ j=jcol(ix,iy,iz)
+ if(icol/=qcols(j,ix,iy,iz))then
+ b(ix,iy,iz)=b(ix,iy,iz)+at
+ cycle
+ else
+ jcol(ix,iy,iz)=j-1_fpi
+ dix=dixs(ix,iy,iz,j); diy=diys(ix,iy,iz,j); diz=dizs(ix,iy,iz,j)
+ hs=hss(j,ix,iy,iz)
+ call blinfil(nfil,hs,h,fil,ff); if(ff)return
+ b(ix,iy,iz)=b(ix,iy,iz)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i; diyi=diy*i; dizi=diz*i
+ b(ix+dixi,iy+diyi,iz+dizi)=b(ix+dixi,iy+diyi,iz+dizi)+filiat
+ b(ix-dixi,iy-diyi,iz-dizi)=b(ix-dixi,iy-diyi,iz-dizi)+filiat
+ enddo
+ endif
+enddo; enddo; enddo
+a=b
+end subroutine dibetax3t
+
+!==================================================================== [dibetat]
+subroutine dibetax4t(kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, kw,lw,mw,nw, &
+ icol,nfil,&
+ qcols,dixs,diys,dizs,diws, jcol,hss,a, ff,ix,iy,iz,iw)
+!=============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: kx,lx,mx,nx, &
+ ky,ly,my,ny, &
+ kz,lz,mz,nz, &
+ kw,lw,mw,nw, &
+ icol,nfil
+integer(fpi),dimension(0:7,lx:mx,ly:my,lz:mz,lw:mw),intent(in ):: qcols
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw,6), intent(in ):: dixs,diys,&
+ dizs,diws
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw), intent(inout):: jcol
+real(dp),dimension(6,lx:mx,ly:my,lz:mz,lw:mw), intent(in ):: hss
+real(dp),dimension(kx:nx,ky:ny,kz:nz,kw:nw), intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz,iw
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(kx:nx,ky:ny,kz:nz,kw:nw):: b
+real(dp) :: filiat,hs,at
+integer(spi) :: h,i, &
+ dix,diy,diz,diw, &
+ dixi,diyi,dizi,diwi
+integer(fpi) :: j
+!==============================================================================
+b=u0
+if(icol==15)jcol=10
+do iw=lw,mw; do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ at=a(ix,iy,iz,iw)
+ j=jcol(ix,iy,iz,iw)
+ if(icol/=qcols(j,ix,iy,iz,iw))then
+ b(ix,iy,iz,iw)=b(ix,iy,iz,iw)+at
+ cycle
+ else
+ jcol(ix,iy,iz,iw)=j-1_fpi
+ dix=dixs(ix,iy,iz,iw,j); diy=diys(ix,iy,iz,iw,j)
+ diz=dizs(ix,iy,iz,iw,j); diw=diws(ix,iy,iz,iw,j)
+ hs=hss(j,ix,iy,iz,iw)
+ call blinfil(nfil,hs,h,fil,ff); if(ff)return
+ b(ix,iy,iz,iw)=b(ix,iy,iz,iw)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i; diyi=diy*i; dizi=diz*i; diwi=diw*i
+ b(ix+dixi,iy+diyi,iz+dizi,iw+diwi)= &
+ b(ix+dixi,iy+diyi,iz+dizi,iw+diwi)+filiat
+ b(ix-dixi,iy-diyi,iz-dizi,iw-diwi)= &
+ b(ix-dixi,iy-diyi,iz-dizi,iw-diwi)+filiat
+ enddo
+ endif
+enddo; enddo; enddo; enddo
+a=b
+end subroutine dibetax4t
+
+!==================================================================== [dibetat]
+subroutine vdibeta1t(nv,kx,lx,mx,nx, nfil, dixs,hss, a, ff,ix)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv,kx,lx,mx,nx,nfil
+integer(fpi),dimension(lx:mx),intent(in ):: dixs
+real(dp), dimension(lx:mx),intent(in ):: hss
+real(dp), dimension(nv,kx:nx),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx):: b
+real(dp),dimension(nv) :: filiat,at
+integer(spi) :: h,i,dix,dixi
+!==============================================================================
+b=u0
+do ix=lx,mx
+ at=a(:,ix)
+ dix=dixs(ix)
+ if(dix==0)then;b(:,ix)=b(:,ix)+at
+ else
+ call blinfil(nfil,hss(ix),h,fil,ff); if(ff)return
+ b(:,ix)=b(:,ix)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i
+ b(:,ix+dixi)=b(:,ix+dixi)+filiat
+ b(:,ix-dixi)=b(:,ix-dixi)+filiat
+ enddo
+ endif
+enddo
+a=b
+end subroutine vdibeta1t
+!==================================================================== [dibetat]
+subroutine vdibeta2t(nv, kx,lx,mx,nx, ky,ly,my,ny, &
+ nfil, dixs,diys,hss, a, ff,ix,iy)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv,&
+ kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my),intent(in ):: dixs,diys
+real(dp), dimension(lx:mx,ly:my),intent(in ):: hss
+real(dp), dimension(nv,kx:nx,ky:ny),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx,ky:ny):: b
+real(dp),dimension(nv) :: filiat,at
+integer(spi) :: h,i,dix,diy,dixi,diyi
+!==============================================================================
+b=u0
+do iy=ly,my; do ix=lx,mx
+ at=a(:,ix,iy)
+ dix=dixs(ix,iy); diy=diys(ix,iy)
+ if(abs(dix)+abs(diy)==0)then;b(:,ix,iy)=b(:,ix,iy)+at
+ else
+ call blinfil(nfil,hss(ix,iy),h,fil,ff); if(ff)return
+ b(:,ix,iy)=b(:,ix,iy)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i; diyi=diy*i
+ b(:,ix+dixi,iy+diyi)=b(:,ix+dixi,iy+diyi)+filiat
+ b(:,ix-dixi,iy-diyi)=b(:,ix-dixi,iy-diyi)+filiat
+ enddo
+ endif
+enddo; enddo
+a=b
+end subroutine vdibeta2t
+!==================================================================== [dibetat]
+subroutine vdibeta3t(nv, kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, &
+ nfil, dixs,diys,dizs,hss, a, ff,ix,iy,iz)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv, &
+ kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ kz,lz,mz,nz,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my,lz:mz),intent(in ):: dixs,diys,dizs
+real(dp), dimension(lx:mx,ly:my,lz:mz),intent(in ):: hss
+real(dp), dimension(nv,kx:nx,ky:ny,kz:nz),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz):: b
+real(dp),dimension(nv) :: filiat,at
+integer(spi) :: h,i, &
+ dix,diy,diz,&
+ dixi,diyi,dizi
+!==============================================================================
+b=u0
+do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ at=a(:,ix,iy,iz)
+ dix=dixs(ix,iy,iz); diy=diys(ix,iy,iz); diz=dizs(ix,iy,iz)
+ if(abs(dix)+abs(diy)+abs(diz)==0)then;b(:,ix,iy,iz)=b(:,ix,iy,iz)+at
+ else
+ call blinfil(nfil, hss(ix,iy,iz),h,fil,ff); if(ff)return
+ b(:,ix,iy,iz)=b(:,ix,iy,iz)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i; diyi=diy*i; dizi=diz*i
+ b(:,ix+dixi,iy+diyi,iz+dizi)=b(:,ix+dixi,iy+diyi,iz+dizi)+filiat
+ b(:,ix-dixi,iy-diyi,iz-dizi)=b(:,ix-dixi,iy-diyi,iz-dizi)+filiat
+ enddo
+ endif
+enddo; enddo; enddo
+a=b
+end subroutine vdibeta3t
+!==================================================================== [dibetat]
+subroutine vdibeta4t(nv, kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, kw,lw,mw,nw, &
+ nfil, dixs,diys,dizs,diws,hss, a,ff,ix,iy,iz,iw)
+!==============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv, &
+ kx,lx,mx,nx,&
+ ky,ly,my,ny,&
+ kz,lz,mz,nz,&
+ kw,lw,mw,nw,&
+ nfil
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw),intent(in ):: dixs,diys,&
+ dizs,diws
+real(dp), dimension(lx:mx,ly:my,lz:mz,lw:mw),intent(in ):: hss
+real(dp), dimension(nv,kx:nx,ky:ny,kz:nz,kw:nw),intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz,iw
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz,kw:nw):: b
+real(dp),dimension(nv) :: filiat,at
+integer(spi) :: h,i, &
+ dix,diy,diz,diw, &
+ dixi,diyi,dizi,diwi
+!==============================================================================
+b=u0
+do iw=lw,mw; do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ at=a(:,ix,iy,iz,iw)
+ dix=dixs(ix,iy,iz,iw); diy=diys(ix,iy,iz,iw)
+ diz=dizs(ix,iy,iz,iw); diw=diws(ix,iy,iz,iw)
+ if(abs(dix)+abs(diy)+abs(diz)+abs(diw)==0)then
+ b(:,ix,iy,iz,iw)=b(:,ix,iy,iz,iw)+at
+ else
+ call blinfil(nfil, hss(ix,iy,iz,iw),h,fil,ff); if(ff)return
+ b(:,ix,iy,iz,iw)=b(:,ix,iy,iz,iw)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i; diyi=diy*i; dizi=diz*i; diwi=diw*i
+ b(:,ix+dixi,iy+diyi,iz+dizi,iw+diwi)= &
+ b(:,ix+dixi,iy+diyi,iz+dizi,iw+diwi)+filiat
+ b(:,ix-dixi,iy-diyi,iz-dizi,iw-diwi)= &
+ b(:,ix-dixi,iy-diyi,iz-dizi,iw-diwi)+filiat
+ enddo
+ endif
+enddo; enddo; enddo; enddo
+a=b
+end subroutine vdibeta4t
+
+!==================================================================== [dibetat]
+subroutine vdibetax3t(nv,kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, icol,nfil,&
+ qcols,dixs,diys,dizs, jcol,hss,a, ff,ix,iy,iz)
+!=============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv, &
+ kx,lx,mx,nx, &
+ ky,ly,my,ny, &
+ kz,lz,mz,nz, &
+ icol,nfil
+integer(fpi),dimension(0:7,lx:mx,ly:my,lz:mz),intent(in ):: qcols
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,6), intent(in ):: dixs,diys,dizs
+integer(fpi),dimension(lx:mx,ly:my,lz:mz), intent(inout):: jcol
+real(dp),dimension(6,lx:mx,ly:my,lz:mz), intent(in ):: hss
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz), intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz):: b
+real(dp),dimension(nv) :: filiat,at
+real(dp) :: hs
+integer(spi) :: h,i, &
+ dix,diy,diz, &
+ dixi,diyi,dizi
+integer(fpi) :: j
+!==============================================================================
+b=u0
+if(icol==7)jcol=6
+do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ at=a(:,ix,iy,iz)
+ j=jcol(ix,iy,iz)
+ if(icol/=qcols(j,ix,iy,iz))then
+ b(:,ix,iy,iz)=b(:,ix,iy,iz)+at
+ cycle
+ else
+ jcol(ix,iy,iz)=j-1_fpi
+ dix=dixs(ix,iy,iz,j); diy=diys(ix,iy,iz,j); diz=dizs(ix,iy,iz,j)
+ hs=hss(j,ix,iy,iz)
+ call blinfil(nfil,hs,h,fil,ff); if(ff)return
+ b(:,ix,iy,iz)=b(:,ix,iy,iz)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i; diyi=diy*i; dizi=diz*i
+ b(:,ix+dixi,iy+diyi,iz+dizi)=b(:,ix+dixi,iy+diyi,iz+dizi)+filiat
+ b(:,ix-dixi,iy-diyi,iz-dizi)=b(:,ix-dixi,iy-diyi,iz-dizi)+filiat
+ enddo
+ endif
+enddo; enddo; enddo
+a=b
+end subroutine vdibetax3t
+
+!==================================================================== [dibetat]
+subroutine vdibetax4t(nv,kx,lx,mx,nx, ky,ly,my,ny, kz,lz,mz,nz, kw,lw,mw,nw, &
+ icol,nfil,&
+ qcols,dixs,diys,dizs,diws, jcol,hss,a, ff,ix,iy,iz,iw)
+!=============================================================================
+use jp_pkind, only: spi,dp; use jp_pkind2, only: fpi
+use jp_pietc, only: u0
+implicit none
+integer(spi), intent(in ):: nv, &
+ kx,lx,mx,nx, &
+ ky,ly,my,ny, &
+ kz,lz,mz,nz, &
+ kw,lw,mw,nw, &
+ icol,nfil
+integer(fpi),dimension(0:7,lx:mx,ly:my,lz:mz,lw:mw),intent(in ):: qcols
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw,6), intent(in ):: dixs,diys,&
+ dizs,diws
+integer(fpi),dimension(lx:mx,ly:my,lz:mz,lw:mw), intent(inout):: jcol
+real(dp),dimension(6,lx:mx,ly:my,lz:mz,lw:mw), intent(in ):: hss
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz,kw:nw), intent(inout):: a
+logical, intent( out):: ff
+integer(spi), intent( out):: ix,iy,iz,iw
+!------------------------------------------------------------------------------
+real(dp),dimension(0:nfil) :: fil
+real(dp),dimension(nv,kx:nx,ky:ny,kz:nz,kw:nw):: b
+real(dp),dimension(nv) :: filiat,at
+real(dp) :: hs
+integer(spi) :: h,i, &
+ dix,diy,diz,diw, &
+ dixi,diyi,dizi,diwi
+integer(fpi) :: j
+!==============================================================================
+b=u0
+if(icol==15)jcol=10
+do iw=lw,mw; do iz=lz,mz; do iy=ly,my; do ix=lx,mx
+ at=a(:,ix,iy,iz,iw)
+ j=jcol(ix,iy,iz,iw)
+ if(icol/=qcols(j,ix,iy,iz,iw))then
+ b(:,ix,iy,iz,iw)=b(:,ix,iy,iz,iw)+at
+ cycle
+ else
+ jcol(ix,iy,iz,iw)=j-1_fpi
+ dix=dixs(ix,iy,iz,iw,j); diy=diys(ix,iy,iz,iw,j)
+ diz=dizs(ix,iy,iz,iw,j); diw=diws(ix,iy,iz,iw,j)
+ hs=hss(j,ix,iy,iz,iw)
+ call blinfil(nfil,hs,h,fil,ff); if(ff)return
+ b(:,ix,iy,iz,iw)=b(:,ix,iy,iz,iw)+fil(0)*at
+ do i=1,h
+ filiat=fil(i)*at; dixi=dix*i; diyi=diy*i; dizi=diz*i; diwi=diw*i
+ b(:,ix+dixi,iy+diyi,iz+dizi,iw+diwi)= &
+ b(:,ix+dixi,iy+diyi,iz+dizi,iw+diwi)+filiat
+ b(:,ix-dixi,iy-diyi,iz-dizi,iw-diwi)= &
+ b(:,ix-dixi,iy-diyi,iz-dizi,iw-diwi)+filiat
+ enddo
+ endif
+enddo; enddo; enddo; enddo
+a=b
+end subroutine vdibetax4t
+
+end module jp_pbfil3
+
+!#
diff --git a/src/mgbf/jp_pietc.f90 b/src/mgbf/jp_pietc.f90
new file mode 100644
index 0000000000..b102d22b7a
--- /dev/null
+++ b/src/mgbf/jp_pietc.f90
@@ -0,0 +1,111 @@
+module jp_pietc
+!$$$ module documentation block
+! . . . .
+! module: jp_pietc
+! prgmmr: purser org: NOAA/EMC date: 2014
+!
+! abstract: Some of the commonly used constants (pi etc)
+! mainly for double-precision subroutines.
+!
+! module history log:
+!
+! Subroutines Included:
+!
+! Functions Included:
+!
+! remarks:
+! ms10 etc are needed to satisfy the some (eg., gnu fortran) compilers'
+! more rigorous standards regarding the way "data" statements are initialized.
+! Zero and the first few units are u0,u1,u2, etc., their reciprocals being,
+! o2,o3 etc and their square roots, r2,r3. Reciprocal roots are or2,or3 etc.
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+use jp_pkind, only: dp,dpc
+implicit none
+logical ,parameter:: T=.true.,F=.false. !<- for pain-relief in logical ops
+real(dp),parameter:: &
+ u0=0,u1=1,mu1=-u1,u2=2,mu2=-u2,u3=3,mu3=-u3,u4=4,mu4=-u4,u5=5,mu5=-u5, &
+ u6=6,mu6=-u6,o2=u1/2,o3=u1/3,o4=u1/4,o5=u1/5,o6=u1/6, &
+ pi =3.1415926535897932384626433832795028841971693993751058209749e0_dp, &
+ pi2=6.2831853071795864769252867665590057683943387987502116419498e0_dp, &
+ pih=1.5707963267948966192313216916397514420985846996875529104874e0_dp, &
+ rpi=1.7724538509055160272981674833411451827975494561223871282138e0_dp, &
+! Important square-roots
+ r2 =1.4142135623730950488016887242096980785696718753769480731766e0_dp, &
+ r3 =1.7320508075688772935274463415058723669428052538103806280558e0_dp, &
+ r5 =2.2360679774997896964091736687312762354406183596115257242708e0_dp, &
+ or2=u1/r2,or3=u1/r3,or5=u1/r5, &
+! Golden number:
+ phi=1.6180339887498948482045868343656381177203091798057628621354e0_dp, &
+! Euler-Mascheroni constant:
+ euler=0.57721566490153286060651209008240243104215933593992359880e0_dp, &
+! Degree to radians; radians to degrees:
+ dtor=pi/180,rtod=180/pi, &
+! Sines of all main fractions of 90 degrees (down to ninths):
+ s10=.173648177666930348851716626769314796000375677184069387236241e0_dp,&
+ s11=.195090322016128267848284868477022240927691617751954807754502e0_dp,&
+ s13=.222520933956314404288902564496794759466355568764544955311987e0_dp,&
+ s15=.258819045102520762348898837624048328349068901319930513814003e0_dp,&
+ s18=.309016994374947424102293417182819058860154589902881431067724e0_dp,&
+ s20=.342020143325668733044099614682259580763083367514160628465048e0_dp,&
+ s22=.382683432365089771728459984030398866761344562485627041433800e0_dp,&
+ s26=.433883739117558120475768332848358754609990727787459876444547e0_dp,&
+ s30=o2, &
+ s34=.555570233019602224742830813948532874374937190754804045924153e0_dp,&
+ s36=.587785252292473129168705954639072768597652437643145991072272e0_dp,&
+ s39=.623489801858733530525004884004239810632274730896402105365549e0_dp,&
+ s40=.642787609686539326322643409907263432907559884205681790324977e0_dp,&
+ s45=or2, &
+ s50=.766044443118978035202392650555416673935832457080395245854045e0_dp,&
+ s51=.781831482468029808708444526674057750232334518708687528980634e0_dp,&
+ s54=.809016994374947424102293417182819058860154589902881431067724e0_dp,&
+ s56=.831469612302545237078788377617905756738560811987249963446124e0_dp,&
+ s60=r3*o2, &
+ s64=.900968867902419126236102319507445051165919162131857150053562e0_dp,&
+ s68=.923879532511286756128183189396788286822416625863642486115097e0_dp,&
+ s70=.939692620785908384054109277324731469936208134264464633090286e0_dp,&
+ s72=.951056516295153572116439333379382143405698634125750222447305e0_dp,&
+ s75=.965925826289068286749743199728897367633904839008404550402343e0_dp,&
+ s77=.974927912181823607018131682993931217232785800619997437648079e0_dp,&
+ s79=.980785280403230449126182236134239036973933730893336095002916e0_dp,&
+ s80=.984807753012208059366743024589523013670643251719842418790025e0_dp,&
+! ... and their minuses:
+ ms10=-s10,ms11=-s11,ms13=-s13,ms15=-s15,ms18=-s18,ms20=-s20,ms22=-s22,&
+ ms26=-s26,ms30=-s30,ms34=-s34,ms36=-s36,ms39=-s39,ms40=-s40,ms45=-s45,&
+ ms50=-s50,ms51=-s51,ms54=-s54,ms56=-s56,ms60=-s60,ms64=-s64,ms68=-s68,&
+ ms70=-s70,ms72=-s72,ms75=-s75,ms77=-s77,ms79=-s79,ms80=-s80
+
+complex(dpc),parameter:: &
+ c0=(u0,u0),c1=(u1,u0),mc1=-c1,ci=(u0,u1),mci=-ci,cipi=ci*pi, &
+! Main fractional rotations, as unimodualr complex numbers:
+ z000=c1 ,z010=( s80,s10),z011=( s79,s11),z013=( s77,s13),&
+ z015=( s75,s15),z018=( s72,s18),z020=( s70,s20),z022=( s68,s22),&
+ z026=( s64,s26),z030=( s60,s30),z034=( s56,s34),z036=( s54,s36),&
+ z039=( s51,s39),z040=( s50,s40),z045=( s45,s45),z050=( s40,s50),&
+ z051=( s39,s51),z054=( s36,s54),z056=( s34,s56),z060=( s30,s60),&
+ z064=( s26,s64),z068=( s22,s68),z070=( s20,s70),z072=( s18,s72),&
+ z075=( s15,s75),z077=( s13,s77),z079=( s11,s79),z080=( s10,s80),&
+ z090=ci, z100=(ms10,s80),z101=(ms11,s79),z103=(ms13,s77),&
+ z105=(ms15,s75),z108=(ms18,s72),z110=(ms20,s70),z112=(ms22,s68),&
+ z116=(ms26,s64),z120=(ms30,s60),z124=(ms34,s56),z126=(ms36,s54),&
+ z129=(ms39,s51),z130=(ms40,s50),z135=(ms45,s45),z140=(ms50,s40),&
+ z141=(ms51,s39),z144=(ms54,s36),z146=(ms56,s34),z150=(ms60,s30),&
+ z154=(ms64,s26),z158=(ms68,s22),z160=(ms70,s20),z162=(ms72,s18),&
+ z165=(ms75,s15),z167=(ms77,s13),z169=(ms79,s11),z170=(ms80,s10),&
+ z180=-z000,z190=-z010,z191=-z011,z193=-z013,z195=-z015,z198=-z018,&
+ z200=-z020,z202=-z022,z206=-z026,z210=-z030,z214=-z034,z216=-z036,&
+ z219=-z039,z220=-z040,z225=-z045,z230=-z050,z231=-z051,z234=-z054,&
+ z236=-z056,z240=-z060,z244=-z064,z248=-z068,z250=-z070,z252=-z072,&
+ z255=-z075,z257=-z077,z259=-z079,z260=-z080,z270=-z090,z280=-z100,&
+ z281=-z101,z283=-z103,z285=-z105,z288=-z108,z290=-z110,z292=-z112,&
+ z296=-z116,z300=-z120,z304=-z124,z306=-z126,z309=-z129,z310=-z130,&
+ z315=-z135,z320=-z140,z321=-z141,z324=-z144,z326=-z146,z330=-z150,&
+ z334=-z154,z338=-z158,z340=-z160,z342=-z162,z345=-z165,z347=-z167,&
+ z349=-z169,z350=-z170
+end module jp_pietc
diff --git a/src/mgbf/jp_pietc_s.f90 b/src/mgbf/jp_pietc_s.f90
new file mode 100644
index 0000000000..8f3097225b
--- /dev/null
+++ b/src/mgbf/jp_pietc_s.f90
@@ -0,0 +1,113 @@
+module jp_pietc_s
+!$$$ module documentation block
+! . . . .
+! module: jp_pietc_s
+! prgmmr: purser org: NOAA/EMC date: 2014
+!
+! abstract: Some of the commonly used constants (pi etc)
+!
+! module history log:
+!
+! Subroutines Included:
+!
+! Functions Included:
+!
+! remarks:
+! ms10 etc are needed to satisfy the some (eg., gnu fortran) compilers'
+! more rigorous standards regarding the way "data" statements are initialized.
+! Zero and the first few units are u0,u1,u2, etc., their reciprocals being,
+! o2,o3 etc and their square roots, r2,r3. Reciprocal roots are or2,or3 etc.
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+!=============================================================================
+use mpi
+use jp_pkind, only: sp,spc
+implicit none
+logical ,parameter:: T=.true.,F=.false. !<- for pain-relief in logical ops
+real(sp),parameter:: &
+ u0=0_sp,u1=1_sp,mu1=-u1,u2=2_sp,mu2=-u2,u3=3_sp,mu3=-u3,u4=4_sp, &
+ mu4=-u4,u5=5_sp,mu5=-u5,u6=6_sp,mu6=-u6,o2=u1/u2,o3=u1/u3,o4=u1/u4, &
+ o5=u1/u5,o6=u1/u6,mo2=-o2,mo3=-o3,mo4=-o4,mo5=-o5,mo6=-06, &
+ pi =3.1415926535897932384626433832795028841971693993751058209749e0_sp, &
+ pi2=6.2831853071795864769252867665590057683943387987502116419498e0_sp, &
+ pih=1.5707963267948966192313216916397514420985846996875529104874e0_sp, &
+ rpi=1.7724538509055160272981674833411451827975494561223871282138e0_sp, &
+! Important square-roots
+ r2 =1.4142135623730950488016887242096980785696718753769480731766e0_sp, &
+ r3 =1.7320508075688772935274463415058723669428052538103806280558e0_sp, &
+ r5 =2.2360679774997896964091736687312762354406183596115257242708e0_sp, &
+ or2=u1/r2,or3=u1/r3,or5=u1/r5, &
+! Golden number:
+ phi=1.6180339887498948482045868343656381177203091798057628621354e0_sp, &
+! Euler-Mascheroni constant:
+ euler=0.57721566490153286060651209008240243104215933593992359880e0_sp, &
+! Degree to radians; radians to degrees:
+ dtor=pi/180,rtod=180/pi, &
+! Sines of all main fractions of 90 degrees (down to ninths):
+ s10=.173648177666930348851716626769314796000375677184069387236241e0_sp,&
+ s11=.195090322016128267848284868477022240927691617751954807754502e0_sp,&
+ s13=.222520933956314404288902564496794759466355568764544955311987e0_sp,&
+ s15=.258819045102520762348898837624048328349068901319930513814003e0_sp,&
+ s18=.309016994374947424102293417182819058860154589902881431067724e0_sp,&
+ s20=.342020143325668733044099614682259580763083367514160628465048e0_sp,&
+ s22=.382683432365089771728459984030398866761344562485627041433800e0_sp,&
+ s26=.433883739117558120475768332848358754609990727787459876444547e0_sp,&
+ s30=o2, &
+ s34=.555570233019602224742830813948532874374937190754804045924153e0_sp,&
+ s36=.587785252292473129168705954639072768597652437643145991072272e0_sp,&
+ s39=.623489801858733530525004884004239810632274730896402105365549e0_sp,&
+ s40=.642787609686539326322643409907263432907559884205681790324977e0_sp,&
+ s45=or2, &
+ s50=.766044443118978035202392650555416673935832457080395245854045e0_sp,&
+ s51=.781831482468029808708444526674057750232334518708687528980634e0_sp,&
+ s54=.809016994374947424102293417182819058860154589902881431067724e0_sp,&
+ s56=.831469612302545237078788377617905756738560811987249963446124e0_sp,&
+ s60=r3*o2, &
+ s64=.900968867902419126236102319507445051165919162131857150053562e0_sp,&
+ s68=.923879532511286756128183189396788286822416625863642486115097e0_sp,&
+ s70=.939692620785908384054109277324731469936208134264464633090286e0_sp,&
+ s72=.951056516295153572116439333379382143405698634125750222447305e0_sp,&
+ s75=.965925826289068286749743199728897367633904839008404550402343e0_sp,&
+ s77=.974927912181823607018131682993931217232785800619997437648079e0_sp,&
+ s79=.980785280403230449126182236134239036973933730893336095002916e0_sp,&
+ s80=.984807753012208059366743024589523013670643251719842418790025e0_sp,&
+! ... and their minuses:
+ ms10=-s10,ms11=-s11,ms13=-s13,ms15=-s15,ms18=-s18,ms20=-s20,ms22=-s22,&
+ ms26=-s26,ms30=-s30,ms34=-s34,ms36=-s36,ms39=-s39,ms40=-s40,ms45=-s45,&
+ ms50=-s50,ms51=-s51,ms54=-s54,ms56=-s56,ms60=-s60,ms64=-s64,ms68=-s68,&
+ ms70=-s70,ms72=-s72,ms75=-s75,ms77=-s77,ms79=-s79,ms80=-s80
+
+complex(spc),parameter:: &
+ c0=(u0,u0),c1=(u1,u0),mc1=-c1,ci=(u0,u1),mci=-ci,cipi=ci*pi, &
+! Main fractional rotations, as unimodualr complex numbers:
+ z000=c1 ,z010=( s80,s10),z011=( s79,s11),z013=( s77,s13),&
+ z015=( s75,s15),z018=( s72,s18),z020=( s70,s20),z022=( s68,s22),&
+ z026=( s64,s26),z030=( s60,s30),z034=( s56,s34),z036=( s54,s36),&
+ z039=( s51,s39),z040=( s50,s40),z045=( s45,s45),z050=( s40,s50),&
+ z051=( s39,s51),z054=( s36,s54),z056=( s34,s56),z060=( s30,s60),&
+ z064=( s26,s64),z068=( s22,s68),z070=( s20,s70),z072=( s18,s72),&
+ z075=( s15,s75),z077=( s13,s77),z079=( s11,s79),z080=( s10,s80),&
+ z090=ci, z100=(ms10,s80),z101=(ms11,s79),z103=(ms13,s77),&
+ z105=(ms15,s75),z108=(ms18,s72),z110=(ms20,s70),z112=(ms22,s68),&
+ z116=(ms26,s64),z120=(ms30,s60),z124=(ms34,s56),z126=(ms36,s54),&
+ z129=(ms39,s51),z130=(ms40,s50),z135=(ms45,s45),z140=(ms50,s40),&
+ z141=(ms51,s39),z144=(ms54,s36),z146=(ms56,s34),z150=(ms60,s30),&
+ z154=(ms64,s26),z158=(ms68,s22),z160=(ms70,s20),z162=(ms72,s18),&
+ z165=(ms75,s15),z167=(ms77,s13),z169=(ms79,s11),z170=(ms80,s10),&
+ z180=-z000,z190=-z010,z191=-z011,z193=-z013,z195=-z015,z198=-z018,&
+ z200=-z020,z202=-z022,z206=-z026,z210=-z030,z214=-z034,z216=-z036,&
+ z219=-z039,z220=-z040,z225=-z045,z230=-z050,z231=-z051,z234=-z054,&
+ z236=-z056,z240=-z060,z244=-z064,z248=-z068,z250=-z070,z252=-z072,&
+ z255=-z075,z257=-z077,z259=-z079,z260=-z080,z270=-z090,z280=-z100,&
+ z281=-z101,z283=-z103,z285=-z105,z288=-z108,z290=-z110,z292=-z112,&
+ z296=-z116,z300=-z120,z304=-z124,z306=-z126,z309=-z129,z310=-z130,&
+ z315=-z135,z320=-z140,z321=-z141,z324=-z144,z326=-z146,z330=-z150,&
+ z334=-z154,z338=-z158,z340=-z160,z342=-z162,z345=-z165,z347=-z167,&
+ z349=-z169,z350=-z170
+end module jp_pietc_s
+
diff --git a/src/mgbf/jp_pkind.f90 b/src/mgbf/jp_pkind.f90
new file mode 100644
index 0000000000..cdbf19f4eb
--- /dev/null
+++ b/src/mgbf/jp_pkind.f90
@@ -0,0 +1,34 @@
+module jp_pkind
+!$$$ module documentation block
+! . . . .
+! module: jp_pkind
+!
+! abstract: Kinds for single- and double-precision
+!
+! module history log:
+!
+! Subroutines Included:
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+integer,parameter:: spi=selected_int_kind(6),&
+ dpi=selected_int_kind(12),&
+ sp =selected_real_kind(6,30),&
+ dp =selected_real_kind(15,300),&
+ spc=sp,dpc=dp
+!private:: one_dpi; integer(8),parameter:: one_dpi=1
+!integer,parameter:: dpi=kind(one_dpi)
+!integer,parameter:: sp=kind(1.0)
+!integer,parameter:: dp=kind(1.0d0)
+!integer,parameter:: spc=kind((1.0,1.0))
+!integer,parameter:: dpc=kind((1.0d0,1.0d0))
+end module jp_pkind
diff --git a/src/mgbf/jp_pkind2.f90 b/src/mgbf/jp_pkind2.f90
new file mode 100644
index 0000000000..3dcecc5635
--- /dev/null
+++ b/src/mgbf/jp_pkind2.f90
@@ -0,0 +1,25 @@
+module jp_pkind2
+!$$$ module documentation block
+! . . . .
+! module: jp_pkind2
+!
+! abstract: Integer kinds for helf- and fourth-precision integers
+!
+! module history log:
+!
+! Subroutines Included:
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+integer,parameter:: hpi=selected_int_kind(3),&
+ fpi=selected_int_kind(2)
+end module jp_pkind2
diff --git a/src/mgbf/jp_pmat.f90 b/src/mgbf/jp_pmat.f90
new file mode 100644
index 0000000000..f139feea06
--- /dev/null
+++ b/src/mgbf/jp_pmat.f90
@@ -0,0 +1,1096 @@
+module jp_pmat
+!$$$ module documentation block
+! . . . .
+! module: jp_pmat
+! prgmmr: fujita org: NOAA/EMC date: 1993
+!
+! abstract: Utility routines for various linear inversions and Cholesky
+!
+! module history log:
+! 2002 purser
+! 2009 purser
+! 2012 purser
+!
+! Subroutines Included:
+! swpvv -
+! inv -
+! ldum -
+! udlmm -
+! l1lm -
+! ldlm -
+! invu -
+! invl -
+!
+! Functions Included:
+!
+! remarks:
+! Originally, these routines were copies of the purely "inversion" members
+! of pmat1.f90 (a most extensive collection of matrix routines -- not just
+! inversions). As well as having both single and double precision versions
+! of each routine, these versions also make provision for a more graceful
+! termination in cases where the system matrix is detected to be
+! essentially singular (and therefore noninvertible). This provision takes
+! the form of an optional "failure flag", FF, which is normally returned
+! as .FALSE., but is returned as .TRUE. when inversion fails.
+! In Sep 2012, these routines were collected together into jp_pmat.f90 so
+! that all the main matrix routines could be in the same library, jp_pmat.a.
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+use jp_pkind, only: sp,dp,spc,dpc
+use jp_pietc, only: t,f
+implicit none
+private
+public:: ldum,udlmm,inv,L1Lm,LdLm,invl,invu
+interface swpvv; module procedure sswpvv,dswpvv,cswpvv; end interface
+interface ldum
+ module procedure sldum,dldum,cldum,sldumf,dldumf,cldumf; end interface
+interface udlmm
+ module procedure sudlmm,dudlmm,cudlmm,sudlmv,dudlmv,cudlmv; end interface
+interface inv
+ module procedure &
+sinvmt, dinvmt, cinvmt, slinmmt, dlinmmt, clinmmt, slinmvt, dlinmvt, clinmvt, &
+sinvmtf,dinvmtf,cinvmtf,slinmmtf,dlinmmtf,clinmmtf,slinmvtf,dlinmvtf,clinmvtf,&
+iinvf
+ end interface
+interface L1Lm; module procedure sL1Lm,dL1Lm,sL1Lmf,dL1Lmf; end interface
+interface LdLm; module procedure sLdLm,dLdLm,sLdLmf,dLdLmf; end interface
+interface invl; module procedure sinvl,dinvl,slinlv,dlinlv; end interface
+interface invu; module procedure sinvu,dinvu,slinuv,dlinuv; end interface
+
+contains
+
+!=============================================================================
+subroutine sswpvv(d,e)! [swpvv]
+!=============================================================================
+! Swap vectors
+!-------------
+real(sp), intent(inout) :: d(:), e(:)
+real(sp) :: tv(size(d))
+!=============================================================================
+tv = d; d = e; e = tv
+end subroutine sswpvv
+!=============================================================================
+subroutine dswpvv(d,e)! [swpvv]
+!=============================================================================
+real(dp), intent(inout) :: d(:), e(:)
+real(dp) :: tv(size(d))
+!=============================================================================
+tv = d; d = e; e = tv
+end subroutine dswpvv
+!=============================================================================
+subroutine cswpvv(d,e)! [swpvv]
+!=============================================================================
+complex(dpc),intent(inout) :: d(:), e(:)
+complex(dpc) :: tv(size(d))
+!=============================================================================
+tv = d; d = e; e = tv
+end subroutine cswpvv
+
+!=============================================================================
+subroutine sinvmt(a)! [inv]
+!=============================================================================
+real(sp),dimension(:,:),intent(INOUT):: a
+logical :: ff
+call sinvmtf(a,ff)
+if(ff)stop 'In sinvmt; Unable to invert matrix'
+end subroutine sinvmt
+!=============================================================================
+subroutine dinvmt(a)! [inv]
+!=============================================================================
+real(dp),dimension(:,:),intent(inout):: a
+logical :: ff
+call dinvmtf(a,ff)
+if(ff)stop 'In dinvmt; Unable to invert matrix'
+end subroutine dinvmt
+!=============================================================================
+subroutine cinvmt(a)! [inv]
+!=============================================================================
+complex(dpc),dimension(:,:),intent(inout):: a
+logical :: ff
+call cinvmtf(a,ff)
+if(ff)stop 'In cinvmt; Unable to invert matrix'
+end subroutine cinvmt
+!=============================================================================
+subroutine sinvmtf(a,ff)! [inv]
+!=============================================================================
+! Invert matrix (or flag if can't)
+!----------------
+real(sp),dimension(:,:),intent(inout):: a
+logical, intent( out):: ff
+integer :: m,i,j,jp,l
+real(sp) :: d
+integer,dimension(size(a,1)) :: ipiv
+!=============================================================================
+m=size(a,1)
+if(m /= size(a,2))stop 'In sinvmtf; matrix passed to sinvmtf is not square'
+! Perform a pivoted L-D-U decomposition on matrix a:
+call sldumf(a,ipiv,d,ff)
+if(ff)then
+ print '(" In sinvmtf; failed call to sldumf")'
+ return
+endif
+
+! Invert upper triangular portion U in place:
+do i=1,m; a(i,i)=1./a(i,i); enddo
+do i=1,m-1
+ do j=i+1,m; a(i,j)=-a(j,j)*dot_product(a(i:j-1,j),a(i,i:j-1)); enddo
+enddo
+
+! Invert lower triangular portion L in place:
+do j=1,m-1; jp=j+1
+ do i=jp,m; a(i,j)=-a(i,j)-dot_product(a(jp:i-1,j),a(i,jp:i-1)); enddo
+enddo
+
+! Form the product of U**-1 and L**-1 in place
+do j=1,m-1; jp=j+1
+ do i=1,j; a(i,j)=a(i,j)+dot_product(a(jp:m,j),a(i,jp:m)); enddo
+ do i=jp,m; a(i,j)=dot_product(a(i:m,j),a(i,i:m)); enddo
+enddo
+
+! Permute columns according to ipiv
+do j=m-1,1,-1; l=ipiv(j); call sswpvv(a(:,j),a(:,l)); enddo
+end subroutine sinvmtf
+!=============================================================================
+subroutine dinvmtf(a,ff)! [inv]
+!=============================================================================
+real(DP),dimension(:,:),intent(INOUT):: a
+logical, intent( OUT):: ff
+integer :: m,i,j,jp,l
+real(DP) :: d
+integer, dimension(size(a,1)) :: ipiv
+!=============================================================================
+m=size(a,1)
+if(m /= size(a,2))stop 'In inv; matrix passed to dinvmtf is not square'
+! Perform a pivoted L-D-U decomposition on matrix a:
+call dldumf(a,ipiv,d,ff)
+if(ff)then
+ print '(" In dinvmtf; failed call to dldumf")'
+ return
+endif
+
+! Invert upper triangular portion U in place:
+do i=1,m; a(i,i)=1/a(i,i); enddo
+do i=1,m-1
+ do j=i+1,m; a(i,j)=-a(j,j)*dot_product(a(i:j-1,j),a(i,i:j-1)); enddo
+enddo
+
+! Invert lower triangular portion L in place:
+do j=1,m-1; jp=j+1
+ do i=jp,m; a(i,j)=-a(i,j)-dot_product(a(jp:i-1,j),a(i,jp:i-1)); enddo
+enddo
+
+! Form the product of U**-1 and L**-1 in place
+do j=1,m-1; jp=j+1
+ do i=1,j; a(i,j)=a(i,j)+dot_product(a(jp:m,j),a(i,jp:m)); enddo
+ do i=jp,m; a(i,j)=dot_product(a(i:m,j),a(i,i:m)); enddo
+enddo
+
+! Permute columns according to ipiv
+do j=m-1,1,-1; l=ipiv(j); call dswpvv(a(:,j),a(:,l)); enddo
+end subroutine dinvmtf
+!=============================================================================
+subroutine cinvmtf(a,ff)! [inv]
+!=============================================================================
+complex(dpc),dimension(:,:),intent(INOUT):: a
+logical, intent( OUT):: ff
+integer :: m,i,j,jp,l
+complex(dpc) :: d
+integer, dimension(size(a,1)) :: ipiv
+!=============================================================================
+m=size(a,1)
+if(m /= size(a,2))stop 'In inv; matrix passed to cinvmtf is not square'
+! Perform a pivoted L-D-U decomposition on matrix a:
+call cldumf(a,ipiv,d,ff)
+if(ff)then
+ print '(" In cinvmtf; failed call to cldumf")'
+ return
+endif
+
+! Invert upper triangular portion U in place:
+do i=1,m; a(i,i)=1/a(i,i); enddo
+do i=1,m-1
+ do j=i+1,m; a(i,j)=-a(j,j)*sum(a(i:j-1,j)*a(i,i:j-1)); enddo
+enddo
+
+! Invert lower triangular portion L in place:
+do j=1,m-1; jp=j+1
+ do i=jp,m; a(i,j)=-a(i,j)-sum(a(jp:i-1,j)*a(i,jp:i-1)); enddo
+enddo
+
+! Form the product of U**-1 and L**-1 in place
+do j=1,m-1; jp=j+1
+ do i=1,j; a(i,j)=a(i,j)+sum(a(jp:m,j)*a(i,jp:m)); enddo
+ do i=jp,m; a(i,j)=sum(a(i:m,j)*a(i,i:m)); enddo
+enddo
+
+! Permute columns according to ipiv
+do j=m-1,1,-1; l=ipiv(j); call cswpvv(a(:,j),a(:,l)); enddo
+end subroutine cinvmtf
+
+!=============================================================================
+subroutine slinmmt(a,b)! [inv]
+!=============================================================================
+real(sp),dimension(:,:),intent(inout):: a,b
+logical :: ff
+call slinmmtf(a,b,ff)
+if(ff)stop 'In slinmmt; unable to invert linear system'
+end subroutine slinmmt
+!=============================================================================
+subroutine dlinmmt(a,b)! [inv]
+!=============================================================================
+real(dp),dimension(:,:),intent(inout):: a,b
+logical :: ff
+call dlinmmtf(a,b,ff)
+if(ff)stop 'In dlinmmt; unable to invert linear system'
+end subroutine dlinmmt
+!=============================================================================
+subroutine clinmmt(a,b)! [inv]
+!=============================================================================
+complex(dpc),dimension(:,:),intent(inout):: a,b
+logical :: ff
+call clinmmtf(a,b,ff)
+if(ff)stop 'In clinmmt; unable to invert linear system'
+end subroutine clinmmt
+!=============================================================================
+subroutine slinmmtf(a,b,ff)! [inv]
+!=============================================================================
+real(SP), dimension(:,:),intent(INOUT):: a,b
+logical, intent( OUT):: ff
+integer,dimension(size(a,1)) :: ipiv
+integer :: m
+real(sp) :: d
+!=============================================================================
+m=size(a,1)
+if(m /= size(a,2))stop 'In inv; matrix passed to slinmmtf is not square'
+if(m /= size(b,1))&
+ stop 'In inv; matrix and vectors in slinmmtf have unmatched sizes'
+call sldumf(a,ipiv,d,ff)
+if(ff)then
+ print '("In slinmmtf; failed call to sldumf")'
+ return
+endif
+call sudlmm(a,b,ipiv)
+end subroutine slinmmtf
+!=============================================================================
+subroutine dlinmmtf(a,b,ff)! [inv]
+!=============================================================================
+real(dp),dimension(:,:), intent(inout):: a,b
+logical, intent( out):: ff
+integer, dimension(size(a,1)) :: ipiv
+integer :: m
+real(dp) :: d
+!=============================================================================
+m=size(a,1)
+if(m /= size(a,2))stop 'In inv; matrix passed to dlinmmtf is not square'
+if(m /= size(b,1))&
+ stop 'In inv; matrix and vectors in dlinmmtf have unmatched sizes'
+call dldumf(a,ipiv,d,ff)
+if(ff)then
+ print '("In dlinmmtf; failed call to dldumf")'
+ return
+endif
+call dudlmm(a,b,ipiv)
+end subroutine dlinmmtf
+!=============================================================================
+subroutine clinmmtf(a,b,ff)! [inv]
+!=============================================================================
+complex(dpc),dimension(:,:),intent(INOUT):: a,b
+logical, intent( OUT):: ff
+integer, dimension(size(a,1)) :: ipiv
+integer :: m
+complex(dpc) :: d
+!=============================================================================
+m=size(a,1)
+if(m /= size(a,2))stop 'In inv; matrix passed to dlinmmtf is not square'
+if(m /= size(b,1))&
+ stop 'In inv; matrix and vectors in dlinmmtf have unmatched sizes'
+call cldumf(a,ipiv,d,ff)
+if(ff)then
+ print '("In clinmmtf; failed call to cldumf")'
+ return
+endif
+call cudlmm(a,b,ipiv)
+end subroutine clinmmtf
+
+!=============================================================================
+subroutine slinmvt(a,b)! [inv]
+!=============================================================================
+real(sp), dimension(:,:),intent(inout):: a
+real(sp), dimension(:), intent(inout):: b
+logical :: ff
+call slinmvtf(a,b,ff)
+if(ff)stop 'In slinmvt; matrix singular, unable to continue'
+end subroutine slinmvt
+!=============================================================================
+subroutine dlinmvt(a,b)! [inv]
+!=============================================================================
+real(dp), dimension(:,:),intent(inout):: a
+real(dp), dimension(:), intent(inout):: b
+logical :: ff
+call dlinmvtf(a,b,ff)
+if(ff)stop 'In dlinmvt; matrix singular, unable to continue'
+end subroutine dlinmvt
+!=============================================================================
+subroutine clinmvt(a,b)! [inv]
+!=============================================================================
+complex(dpc), dimension(:,:),intent(inout):: a
+complex(dpc), dimension(:), intent(inout):: b
+logical :: ff
+call clinmvtf(a,b,ff)
+if(ff)stop 'In clinmvt; matrix singular, unable to continue'
+end subroutine clinmvt
+!=============================================================================
+subroutine slinmvtf(a,b,ff)! [inv]
+!=============================================================================
+real(sp),dimension(:,:),intent(inout):: a
+real(sp),dimension(:), intent(inout):: b
+logical, intent( out):: ff
+integer,dimension(size(a,1)) :: ipiv
+real(sp) :: d
+!=============================================================================
+if(size(a,1) /= size(a,2).or. size(a,1) /= size(b))&
+ stop 'In inv; In slinmvtf; incompatible array dimensions'
+call sldumf(a,ipiv,d,ff)
+if(ff)then
+ print '("In slinmvtf; failed call to sldumf")'
+ return
+endif
+call sudlmv(a,b,ipiv)
+end subroutine slinmvtf
+!=============================================================================
+subroutine dlinmvtf(a,b,ff)! [inv]
+!=============================================================================
+real(dp),dimension(:,:),intent(inout):: a
+real(dp),dimension(:), intent(inout):: b
+logical, intent( out):: ff
+integer, dimension(size(a,1)) :: ipiv
+real(dp) :: d
+!=============================================================================
+if(size(a,1) /= size(a,2).or. size(a,1) /= size(b))&
+ stop 'In inv; incompatible array dimensions passed to dlinmvtf'
+call dldumf(a,ipiv,d,ff)
+if(ff)then
+ print '("In dlinmvtf; failed call to dldumf")'
+ return
+endif
+call dudlmv(a,b,ipiv)
+end subroutine dlinmvtf
+!=============================================================================
+subroutine clinmvtf(a,b,ff)! [inv]
+!=============================================================================
+complex(dpc),dimension(:,:),intent(inout):: a
+complex(dpc),dimension(:), intent(inout):: b
+logical, intent( out):: ff
+integer, dimension(size(a,1)) :: ipiv
+complex(dpc) :: d
+!=============================================================================
+if(size(a,1) /= size(a,2).or. size(a,1) /= size(b))&
+ stop 'In inv; incompatible array dimensions passed to clinmvtf'
+call cldumf(a,ipiv,d,ff)
+if(ff)then
+ print '("In clinmvtf; failed call to cldumf")'
+ return
+endif
+call cudlmv(a,b,ipiv)
+end subroutine clinmvtf
+
+!=============================================================================
+subroutine iinvf(imat,ff)! [inv]
+!=============================================================================
+! Invert integer square array, imat, if possible, but flag ff=.true.
+! if not possible. (Determinant of imat must be +1 or -1
+!=============================================================================
+integer,dimension(:,:),intent(INOUT):: imat
+logical, intent( OUT):: ff
+!-----------------------------------------------------------------------------
+real(dp),parameter :: eps=1.e-10_dp
+real(dp),dimension(size(imat,1),size(imat,1)):: dmat
+integer :: m,i,j
+!=============================================================================
+m=size(imat,1)
+if(m /= size(imat,2))stop 'In inv; matrix passed to iinvf is not square'
+dmat=imat; call inv(dmat,ff)
+if(.not.ff)then
+ do j=1,m
+ do i=1,m
+ imat(i,j)=nint(dmat(i,j)); if(abs(dmat(i,j)-imat(i,j))>eps)ff=t
+ enddo
+ enddo
+endif
+end subroutine iinvf
+
+!=============================================================================
+subroutine sldum(a,ipiv,d)! [ldum]
+!=============================================================================
+real(sp),intent(inout) :: a(:,:)
+real(sp),intent(out ) :: d
+integer, intent(out ) :: ipiv(:)
+logical :: ff
+call sldumf(a,ipiv,d,ff)
+if(ff)stop 'In sldum; matrix singular, unable to continue'
+end subroutine sldum
+!=============================================================================
+subroutine dldum(a,ipiv,d)! [ldum]
+!=============================================================================
+real(dp),intent(inout) :: a(:,:)
+real(dp),intent(out ) :: d
+integer, intent(out ) :: ipiv(:)
+logical:: ff
+call dldumf(a,ipiv,d,ff)
+if(ff)stop 'In dldum; matrix singular, unable to continue'
+end subroutine dldum
+!=============================================================================
+subroutine cldum(a,ipiv,d)! [ldum]
+!=============================================================================
+complex(dpc),intent(inout) :: a(:,:)
+complex(dpc),intent(out ) :: d
+integer, intent(out ) :: ipiv(:)
+logical:: ff
+call cldumf(a,ipiv,d,ff)
+if(ff)stop 'In cldum; matrix singular, unable to continue'
+end subroutine cldum
+!=============================================================================
+subroutine sldumf(a,ipiv,d,ff)! [ldum]
+!=============================================================================
+! R.J.Purser, NCEP, Washington D.C. 1996
+! SUBROUTINE LDUM
+! perform l-d-u decomposition of square matrix a in place with
+! pivoting.
+!
+! <-> a square matrix to be factorized
+! <-- ipiv array encoding the pivoting sequence
+! <-- d indicator for possible sign change of determinant
+! <-- ff: failure flag, set to .true. when determinant of a vanishes.
+!=============================================================================
+real(SP),intent(INOUT) :: a(:,:)
+real(SP),intent(OUT ) :: d
+integer, intent(OUT ) :: ipiv(:)
+logical, intent(OUT ) :: ff
+integer :: m,i, j, jp, ibig, jm
+real(SP) :: s(size(a,1)), aam, aa, abig, ajj, ajji, aij
+!=============================================================================
+ff=f
+m=size(a,1)
+do i=1,m
+ aam=0
+ do j=1,m
+ aa=abs(a(i,j))
+ if(aa > aam)aam=aa
+ enddo
+ if(aam == 0)then
+ print '("In sldumf; row ",i6," of matrix vanishes")',i
+ ff=t
+ return
+ endif
+ s(i)=1/aam
+enddo
+d=1.
+ipiv(m)=m
+do j=1,m-1
+ jp=j+1
+ abig=s(j)*abs(a(j,j))
+ ibig=j
+ do i=jp,m
+ aa=s(i)*abs(a(i,j))
+ if(aa > abig)then
+ ibig=i
+ abig=aa
+ endif
+ enddo
+! swap rows, recording changed sign of determinant
+ ipiv(j)=ibig
+ if(ibig /= j)then
+ d=-d
+ call sswpvv(a(j,:),a(ibig,:))
+ s(ibig)=s(j)
+ endif
+ ajj=a(j,j)
+ if(ajj == 0)then
+ jm=j-1
+ print '(" failure in sldumf:"/" matrix singular, rank=",i3)',jm
+ ff=t
+ return
+ endif
+ ajji=1/ajj
+ do i=jp,m
+ aij=ajji*a(i,j)
+ a(i,j)=aij
+ a(i,jp:m) = a(i,jp:m) - aij*a(j,jp:m)
+ enddo
+enddo
+end subroutine sldumf
+!=============================================================================
+subroutine DLDUMf(A,IPIV,D,ff)! [ldum]
+!=============================================================================
+real(DP), intent(INOUT) :: a(:,:)
+real(DP), intent(OUT ) :: d
+integer, intent(OUT ) :: ipiv(:)
+logical, intent(OUT ) :: ff
+integer :: m,i, j, jp, ibig, jm
+real(DP) :: s(size(a,1)), aam, aa, abig, ajj, ajji, aij
+!=============================================================================
+ff=f
+m=size(a,1)
+do i=1,m
+ aam=0
+ do j=1,m
+ aa=abs(a(i,j))
+ if(aa > aam)aam=aa
+ enddo
+ if(aam == 0)then
+ print '("In dldumf; row ",i6," of matrix vanishes")',i
+ ff=t
+ return
+ endif
+ s(i)=1/aam
+enddo
+d=1.
+ipiv(m)=m
+do j=1,m-1
+ jp=j+1
+ abig=s(j)*abs(a(j,j))
+ ibig=j
+ do i=jp,m
+ aa=s(i)*abs(a(i,j))
+ if(aa > abig)then
+ ibig=i
+ abig=aa
+ endif
+ enddo
+! swap rows, recording changed sign of determinant
+ ipiv(j)=ibig
+ if(ibig /= j)then
+ d=-d
+ call dswpvv(a(j,:),a(ibig,:))
+ s(ibig)=s(j)
+ endif
+ ajj=a(j,j)
+ if(ajj == 0)then
+ jm=j-1
+ print '(" Failure in dldumf:"/" matrix singular, rank=",i3)',jm
+ ff=t
+ return
+ endif
+ ajji=1/ajj
+ do i=jp,m
+ aij=ajji*a(i,j)
+ a(i,j)=aij
+ a(i,jp:m) = a(i,jp:m) - aij*a(j,jp:m)
+ enddo
+enddo
+end subroutine DLDUMf
+!=============================================================================
+subroutine cldumf(a,ipiv,d,ff)! [ldum]
+!=============================================================================
+use jp_pietc, only: c0
+complex(dpc), intent(INOUT) :: a(:,:)
+complex(dpc), intent(OUT ) :: d
+integer, intent(OUT ) :: ipiv(:)
+logical, intent(OUT ) :: ff
+integer :: m,i, j, jp, ibig, jm
+complex(dpc) :: ajj, ajji, aij
+real(dp) :: aam,aa,abig
+real(dp),dimension(size(a,1)):: s
+!=============================================================================
+ff=f
+m=size(a,1)
+do i=1,m
+ aam=0
+ do j=1,m
+ aa=abs(a(i,j))
+ if(aa > aam)aam=aa
+ enddo
+ if(aam == 0)then
+ print '("In cldumf; row ",i6," of matrix vanishes")',i
+ ff=t
+ return
+ endif
+ s(i)=1/aam
+enddo
+d=1.
+ipiv(m)=m
+do j=1,m-1
+ jp=j+1
+ abig=s(j)*abs(a(j,j))
+ ibig=j
+ do i=jp,m
+ aa=s(i)*abs(a(i,j))
+ if(aa > abig)then
+ ibig=i
+ abig=aa
+ endif
+ enddo
+! swap rows, recording changed sign of determinant
+ ipiv(j)=ibig
+ if(ibig /= j)then
+ d=-d
+ call cswpvv(a(j,:),a(ibig,:))
+ s(ibig)=s(j)
+ endif
+ ajj=a(j,j)
+ if(ajj == c0)then
+ jm=j-1
+ print '(" Failure in cldumf:"/" matrix singular, rank=",i3)',jm
+ ff=t
+ return
+ endif
+ ajji=1/ajj
+ do i=jp,m
+ aij=ajji*a(i,j)
+ a(i,j)=aij
+ a(i,jp:m) = a(i,jp:m) - aij*a(j,jp:m)
+ enddo
+enddo
+end subroutine cldumf
+
+!=============================================================================
+subroutine sudlmm(a,b,ipiv)! [udlmm]
+!=============================================================================
+! R.J.Purser, National Meteorological Center, Washington D.C. 1993
+! SUBROUTINE UDLMM
+! use l-u factors in A to back-substitute for several rhs in B, using ipiv to
+! define the pivoting permutation used in the l-u decomposition.
+!
+! --> A L-D-U factorization of linear system matrux
+! <-> B rt-hand-sides vectors on input, corresponding solutions on return
+! --> IPIV array encoding the pivoting sequence
+!=============================================================================
+integer, dimension(:), intent(in) :: ipiv
+real(sp),dimension(:,:),intent(in) :: a
+real(sp),dimension(:,:),intent(inout) :: b
+integer :: m,i, k, l
+real(sp) :: s,aiii
+!=============================================================================
+m=size(a,1)
+do k=1,size(b,2) !loop over columns of b
+ do i=1,m
+ l=ipiv(i)
+ s=b(l,k)
+ b(l,k)=b(i,k)
+ s = s - sum(b(1:i-1,k)*a(i,1:i-1))
+ b(i,k)=s
+ enddo
+ b(m,k)=b(m,k)/a(m,m)
+ do i=m-1,1,-1
+ aiii=1/a(i,i)
+ b(i,k) = b(i,k) - sum(b(i+1:m,k)*a(i,i+1:m))
+ b(i,k)=b(i,k)*aiii
+ enddo
+enddo
+end subroutine sudlmm
+!=============================================================================
+subroutine dudlmm(a,b,ipiv)! [udlmm]
+!=============================================================================
+integer, dimension(:), intent(in ) :: ipiv
+real(dp), dimension(:,:),intent(in ) :: a
+real(dp), dimension(:,:),intent(inout) :: b
+integer :: m,i, k, l
+real(dp) :: s,aiii
+!=============================================================================
+m=size(a,1)
+do k=1, size(b,2)!loop over columns of b
+ do i=1,m
+ l=ipiv(i)
+ s=b(l,k)
+ b(l,k)=b(i,k)
+ s = s - sum(b(1:i-1,k)*a(i,1:i-1))
+ b(i,k)=s
+ enddo
+ b(m,k)=b(m,k)/a(m,m)
+ do i=m-1,1,-1
+ aiii=1/a(i,i)
+ b(i,k) = b(i,k) - sum(b(i+1:m,k)*a(i,i+1:m))
+ b(i,k)=b(i,k)*aiii
+ enddo
+enddo
+end subroutine dudlmm
+!=============================================================================
+subroutine cudlmm(a,b,ipiv)! [udlmm]
+!=============================================================================
+integer, dimension(:), intent(in ) :: ipiv
+complex(dpc),dimension(:,:),intent(in ) :: a
+complex(dpc),dimension(:,:),intent(inout) :: b
+integer :: m,i, k, l
+complex(dpc) :: s,aiii
+!=============================================================================
+m=size(a,1)
+do k=1, size(b,2)!loop over columns of b
+ do i=1,m
+ l=ipiv(i)
+ s=b(l,k)
+ b(l,k)=b(i,k)
+ s = s - sum(b(1:i-1,k)*a(i,1:i-1))
+ b(i,k)=s
+ enddo
+ b(m,k)=b(m,k)/a(m,m)
+ do i=m-1,1,-1
+ aiii=1/a(i,i)
+ b(i,k) = b(i,k) - sum(b(i+1:m,k)*a(i,i+1:m))
+ b(i,k)=b(i,k)*aiii
+ enddo
+enddo
+end subroutine cudlmm
+
+!=============================================================================
+subroutine sudlmv(a,b,ipiv)! [udlmv]
+!=============================================================================
+! R.J.Purser, National Meteorological Center, Washington D.C. 1993
+! SUBROUTINE UDLMV
+! use l-u factors in A to back-substitute for 1 rhs in B, using ipiv to
+! define the pivoting permutation used in the l-u decomposition.
+!
+! --> A L-D-U factorization of linear system matrix
+! <-> B right-hand-side vector on input, corresponding solution on return
+! --> IPIV array encoding the pivoting sequence
+!=============================================================================
+integer, dimension(:), intent(in) :: ipiv
+real(sp),dimension(:,:),intent(in) :: a
+real(sp),dimension(:), intent(inout) :: b
+integer :: m,i, l
+real(sp) :: s,aiii
+!=============================================================================
+m=size(a,1)
+do i=1,m
+ l=ipiv(i)
+ s=b(l)
+ b(l)=b(i)
+ s = s - sum(b(1:i-1)*a(i,1:i-1))
+ b(i)=s
+enddo
+b(m)=b(m)/a(m,m)
+do i=m-1,1,-1
+ aiii=1/a(i,i)
+ b(i) = b(i) - sum(b(i+1:m)*a(i,i+1:m))
+ b(i)=b(i)*aiii
+enddo
+end subroutine sudlmv
+!=============================================================================
+subroutine dudlmv(a,b,ipiv)! [udlmv]
+!=============================================================================
+integer, dimension(:), intent(in ) :: ipiv(:)
+real(dp), dimension(:,:),intent(in ) :: a(:,:)
+real(dp), dimension(:), intent(inout) :: b(:)
+integer :: m,i, l
+real(dp) :: s,aiii
+!=============================================================================
+m=size(a,1)
+do i=1,m
+ l=ipiv(i)
+ s=b(l)
+ b(l)=b(i)
+ s = s - sum(b(1:i-1)*a(i,1:i-1))
+ b(i)=s
+enddo
+b(m)=b(m)/a(m,m)
+do i=m-1,1,-1
+ aiii=1/a(i,i)
+ b(i) = b(i) - sum(b(i+1:m)*a(i,i+1:m))
+ b(i)=b(i)*aiii
+enddo
+end subroutine dudlmv
+!=============================================================================
+subroutine cudlmv(a,b,ipiv)! [udlmv]
+!=============================================================================
+integer, dimension(:), intent(in ) :: ipiv(:)
+complex(dpc),dimension(:,:),intent(in ) :: a(:,:)
+complex(dpc),dimension(:), intent(inout) :: b(:)
+integer :: m,i, l
+complex(dpc) :: s,aiii
+!=============================================================================
+m=size(a,1)
+do i=1,m
+ l=ipiv(i)
+ s=b(l)
+ b(l)=b(i)
+ s = s - sum(b(1:i-1)*a(i,1:i-1))
+ b(i)=s
+enddo
+b(m)=b(m)/a(m,m)
+do i=m-1,1,-1
+ aiii=1/a(i,i)
+ b(i) = b(i) - sum(b(i+1:m)*a(i,i+1:m))
+ b(i)=b(i)*aiii
+enddo
+end subroutine cudlmv
+
+!=============================================================================
+subroutine sl1lm(a,b) ! [l1lm]
+!=============================================================================
+! Cholesky, M -> L*U, U(i,j)=L(j,i)
+!=============================================================================
+real(sp), intent(in ) :: a(:,:)
+real(sp), intent(inout) :: b(:,:)
+!-----------------------------------------------------------------------------
+logical:: ff
+call sl1lmf(a,b,ff)
+if(ff)stop 'In sl1lm; matrix singular, unable to continue'
+end subroutine sl1lm
+!=============================================================================
+subroutine dl1lm(a,b) ! [l1lm]
+!=============================================================================
+! Cholesky, M -> L*U, U(i,j)=L(j,i)
+!=============================================================================
+real(dp), intent(in ) :: a(:,:)
+real(dp), intent(inout) :: b(:,:)
+!-----------------------------------------------------------------------------
+logical:: ff
+call dl1lmf(a,b,ff)
+if(ff)stop 'In dl1lm; matrix singular, unable to continue'
+end subroutine dl1lm
+
+!=============================================================================
+subroutine sl1lmf(a,b,ff)! [L1Lm]
+!=============================================================================
+! Cholesky, M -> L*U, U(i,j)=L(j,i)
+!=============================================================================
+real(sp), intent(IN ) :: a(:,:)
+real(sp), intent(INOUT) :: b(:,:)
+logical :: ff
+!-----------------------------------------------------------------------------
+integer :: m,j, jm, jp, i
+real(sp) :: s, bjji
+!=============================================================================
+m=size(a,1)
+ff=f
+do j=1,m
+ jm=j-1
+ jp=j+1
+ s = a(j,j) - sum(b(j,1:jm)*b(j,1:jm))
+ ff=(S <= 0)
+ if(ff)then
+ print '("sL1Lmf detects nonpositive a, rank=",i6)',jm
+ return
+ endif
+ b(j,j)=sqrt(s)
+ bjji=1/b(j,j)
+ do i=jp,m
+ s = a(i,j) - sum(b(i,1:jm)*b(j,1:jm))
+ b(i,j)=s*bjji
+ enddo
+ b(1:jm,j) = 0
+enddo
+end subroutine sl1lmf
+!=============================================================================
+subroutine dl1lmf(a,b,ff) ! [L1Lm]
+!=============================================================================
+real(dp), intent(IN ) :: a(:,:)
+real(dp), intent(INOUT) :: b(:,:)
+logical :: ff
+!-----------------------------------------------------------------------------
+integer :: m,j, jm, jp, i
+real(dp) :: s, bjji
+!=============================================================================
+m=size(a,1)
+ff=f
+do j=1,m
+ jm=j-1
+ jp=j+1
+ s = a(j,j) - sum(b(j,1:jm)*b(j,1:jm))
+ ff=(s <= 0)
+ if(ff)then
+ print '("dL1LMF detects nonpositive A, rank=",i6)',jm
+ return
+ endif
+ b(j,j)=sqrt(s)
+ bjji=1/b(j,j)
+ do i=jp,m
+ s = a(i,j) - sum(b(i,1:jm)*b(j,1:jm))
+ b(i,j)=s*bjji
+ enddo
+ b(1:jm,j) = 0
+enddo
+return
+end subroutine dl1lmf
+
+!=============================================================================
+subroutine sldlm(a,b,d)! [LdLm]
+!=============================================================================
+! Modified Cholesky decompose Q --> L*D*U, U(i,j)=L(j,i)
+!=============================================================================
+real(sp), intent(IN ):: a(:,:)
+real(sp), intent(INOUT):: b(:,:)
+real(sp), intent( OUT):: d(:)
+!-----------------------------------------------------------------------------
+logical:: ff
+call sldlmf(a,b,d,ff)
+if(ff)stop 'In sldlm; matrix singular, unable to continue'
+end subroutine sldlm
+!=============================================================================
+subroutine dldlm(a,b,d)! [LdLm]
+!=============================================================================
+real(dp), intent(IN ):: a(:,:)
+real(dp), intent(INOUT):: b(:,:)
+real(dp), intent( OUT):: d(:)
+!-----------------------------------------------------------------------------
+logical:: ff
+call dldlmf(a,b,d,ff)
+if(ff)stop 'In dldlm; matrix singular, unable to continue'
+end subroutine dldlm
+
+!=============================================================================
+subroutine sldlmf(a,b,d,ff) ! [LDLM]
+!=============================================================================
+! Modified Cholesky decompose Q --> L*D*U
+!=============================================================================
+real(sp), intent(IN ):: a(:,:)
+real(sp), intent(INOUT):: b(:,:)
+real(sp), intent( OUT):: d(:)
+logical, intent( OUT):: ff
+!-----------------------------------------------------------------------------
+integer :: m,j, jm, jp, i
+real(sp) :: bjji
+!=============================================================================
+m=size(a,1)
+ff=f
+do j=1,m
+ jm=j-1
+ jp=j+1
+ d(j)=a(j,j) - sum(b(1:jm,j)*b(j,1:jm))
+ b(j,j) = 1
+ ff=(d(j) == 0)
+ if(ff)then
+ print '("In sldlmf; singularity of matrix detected")'
+ print '("Rank of matrix: ",i6)',jm
+ return
+ endif
+ bjji=1/d(j)
+ do i=jp,m
+ b(j,i)=a(i,j) - dot_product(b(1:jm,j),b(i,1:jm))
+ b(i,j)=b(j,i)*bjji
+ enddo
+ b(1:jm,j)=0
+enddo
+end subroutine sldlmf
+!=============================================================================
+subroutine dldlmf(a,b,d,ff) ! [LDLM]
+!=============================================================================
+! Modified Cholesky Q --> L*D*U, U(i,j)=L(j,i)
+!=============================================================================
+real(dp), intent(IN ) :: a(:,:)
+real(dp), intent(INOUT) :: b(:,:)
+real(dp), intent( OUT) :: d(:)
+logical, intent( OUT) :: ff
+!-----------------------------------------------------------------------------
+integer :: m,j, jm, jp, i
+real(dp) :: bjji
+!=============================================================================
+m=size(a,1)
+ff=f
+do j=1,m; jm=j-1; jp=j+1
+ d(j)=a(j,j) - sum(b(1:jm,j)*b(j,1:jm))
+ b(j,j) = 1
+ ff=(d(j) == 0)
+ if(ff)then
+ print '("In dldlmf; singularity of matrix detected")'
+ print '("Rank of matrix: ",i6)',jm
+ return
+ endif
+ bjji=1/d(j)
+ do i=jp,m
+ b(j,i)=a(i,j) - dot_product(b(1:jm,j),b(i,1:jm))
+ b(i,j)=b(j,i)*bjji
+ enddo
+ b(1:jm,j)=0
+enddo
+end subroutine dldlmf
+
+!==============================================================================
+subroutine sinvu(a)! [invu]
+!==============================================================================
+! Invert the upper triangular matrix in place by transposing, calling
+! invl, and transposing again.
+!==============================================================================
+real,dimension(:,:),intent(inout):: a
+a=transpose(a); call sinvl(a); a=transpose(a)
+end subroutine sinvu
+!==============================================================================
+subroutine dinvu(a)! [invu]
+!==============================================================================
+real(dp),dimension(:,:),intent(inout):: a
+a=transpose(a); call dinvl(a); a=transpose(a)
+end subroutine dinvu
+!==============================================================================
+subroutine sinvl(a)! [invl]
+!==============================================================================
+! Invert lower triangular matrix in place
+!==============================================================================
+real(sp), intent(inout) :: a(:,:)
+integer :: m,j, i
+m=size(a,1)
+do j=m,1,-1
+ a(1:j-1,j) = 0.0
+ a(j,j)=1./a(j,j)
+ do i=j+1,m
+ a(i,j)=-a(i,i)*sum(a(j:i-1,j)*a(i,j:i-1))
+ enddo
+enddo
+end subroutine sinvl
+!==============================================================================
+subroutine dinvl(a)! [invl]
+!==============================================================================
+real(dp), intent(inout) :: a(:,:)
+integer :: m,j, i
+m=size(a,1)
+do j=m,1,-1
+ a(1:j-1,j) = 0.0
+ a(j,j)=1./a(j,j)
+ do i=j+1,m
+ a(i,j)=-a(i,i)*sum(a(j:i-1,j)*a(i,j:i-1))
+ enddo
+enddo
+end subroutine dinvl
+
+!==============================================================================
+subroutine slinlv(a,u)! [invl]
+!==============================================================================
+! Solve linear system involving lower triangular system matrix.
+!==============================================================================
+real, intent(in ) :: a(:,:)
+real, intent(inout) :: u(:)
+integer :: i
+if(size(a,1) /= size(a,2) .or. size(a,1) /= size(u))&
+ stop 'In slinlv; incompatible array dimensions'
+do i=1,size(u); u(i)=(u(i) - sum(u(:i-1)*a(i,:i-1)))/a(i,i); enddo
+end subroutine slinlv
+!==============================================================================
+subroutine dlinlv(a,u)! [invl]
+!==============================================================================
+real(dp), intent(in ) :: a(:,:)
+real(dp), intent(inout) :: u(:)
+integer :: i
+if(size(a,1) /= size(a,2) .or. size(a,1) /= size(u))&
+ stop 'In dlinlv; incompatible array dimensions'
+do i=1,size(u); u(i)=(u(i) - sum(u(:i-1)*a(i,:i-1)))/a(i,i); enddo
+end subroutine dlinlv
+
+!==============================================================================
+subroutine slinuv(a,u)! [invu]
+!==============================================================================
+! Solve linear system involving upper triangular system matrix.
+!==============================================================================
+real, intent(in ) :: a(:,:)
+real, intent(inout) :: u(:)
+integer :: i
+if(size(a,1) /= size(a,2) .or. size(a,1) /= size(u))&
+ stop 'In linuv; incompatible array dimensions'
+do i=size(u),1,-1; u(i)=(u(i) - sum(a(i+1:,i)*u(i+1:)))/a(i,i); enddo
+end subroutine slinuv
+!==============================================================================
+subroutine dlinuv(a,u)! [invu]
+!==============================================================================
+real(dp), intent(in ) :: a(:,:)
+real(dp), intent(inout) :: u(:)
+integer :: i
+if(size(a,1) /= size(a,2) .or. size(a,1) /= size(u))&
+ stop 'In dlinuv; incompatible array dimensions'
+do i=size(u),1,-1; u(i)=(u(i) - sum(a(i+1:,i)*u(i+1:)))/a(i,i); enddo
+end subroutine dlinuv
+
+end module jp_pmat
+
diff --git a/src/mgbf/jp_pmat4.f90 b/src/mgbf/jp_pmat4.f90
new file mode 100644
index 0000000000..552d5efdeb
--- /dev/null
+++ b/src/mgbf/jp_pmat4.f90
@@ -0,0 +1,2086 @@
+module jp_pmat4
+!$$$ module documentation block
+! . . . .
+! module: jp_pmat4
+! prgmmr: purser org: NOAA/EMC date: 2005-10
+!
+! abstract: Euclidean geometry, geometric (stereographic) projections,
+! related transformations (Mobius)
+!
+! module history log:
+! 2012-05-18 purser
+! 2017-05 purser - Added routines to facilitate manipulation of 3D
+! rotations, their representations by axial vectors,
+! and routines to compute the exponentials of matrices
+! (without resort to eigen methods).
+! Also added Quaternion and spinor representations
+! of 3D rotations, and their conversion routines.
+!
+! Subroutines Included:
+! gram - Right-handed orthogonal basis and rank, nrank. The first
+! nrank basis vectors span the column range of matrix given,
+! OR ("plain" version) simple unpivoted Gram-Schmidt of a
+! square matrix.
+!
+! In addition, we include routines that relate to
+! stereographic projections and some associated mobius
+! transformation utilities, since these complex operations
+! have a strong geometrical flavor.
+! dlltoxy -
+! normalize -
+! rowops -
+! corral -
+! rottoax -
+! axtorot -
+! spintoq -
+! qtospin -
+! rottoq -
+! qtorot -
+! axtoq -
+! qtoax -
+! setem -
+! expmat -
+! zntay -
+! znfun -
+! ctoz -
+! ztoc -
+! setmobius -
+! mobius -
+! mobiusi -
+!
+! Functions Included:
+! absv - Absolute magnitude of vector as its euclidean length
+! normalized - Normalized version of given real vector
+! orthogonalized - Orthogonalized version of second vector rel. to first unit v.
+! cross_product - Vector cross-product of the given 2 vectors
+! outer_product - outer-product matrix of the given 2 vectors
+! triple_product - Scalar triple product of given 3 vectors
+! det - Determinant of given matrix
+! axial - Convert axial-vector <--> 2-form (antisymmetric matrix)
+! diag - Diagnl of given matrix, or diagonal matrix of given elements
+! trace - Trace of given matrix
+! identity - Identity 3*3 matrix, or identity n*n matrix for a given n
+! sarea - Spherical area subtended by three vectors, or by lat-lon
+! increments forming a triangle or quadrilateral
+! huarea - Spherical area subtended by right-angled spherical triangle
+! hav -
+! mulqq -
+!
+! remarks:
+! Package for handy vector and matrix operations in Euclidean geometry.
+! This package is primarily intended for 3D operations and three of the
+! functions (Cross_product, Triple_product and Axial) do not possess simple
+! generalizations to a generic number N of dimensions. The others, while
+! admitting such N-dimensional generalizations, have not all been provided
+! with such generic forms here at the time of writing, though some of these
+! may be added at a future date.
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+use jp_pkind, only: spi,sp,dp,dpc
+implicit none
+private
+public:: absv,normalized,orthogonalized, &
+ cross_product,outer_product,triple_product,det,axial, &
+ diag,trace,identity,sarea,huarea,dlltoxy, &
+ normalize,gram,rowops,corral, &
+ axtoq,qtoax, &
+ rottoax,axtorot,spintoq,qtospin,rottoq,qtorot,mulqq, &
+ expmat,zntay,znfun, &
+ ctoz,ztoc,setmobius, &
+ mobius,mobiusi
+
+interface absv; module procedure absv_s,absv_d; end interface
+interface normalized;module procedure normalized_s,normalized_d;end interface
+interface orthogonalized
+ module procedure orthogonalized_s,orthogonalized_d; end interface
+interface cross_product
+ module procedure cross_product_s,cross_product_d, &
+ triple_cross_product_s,triple_cross_product_d; end interface
+interface outer_product
+ module procedure outer_product_s,outer_product_d,outer_product_i
+ end interface
+interface triple_product
+ module procedure triple_product_s,triple_product_d; end interface
+interface det; module procedure det_s,det_d,det_i,det_id; end interface
+interface axial
+ module procedure axial3_s,axial3_d,axial33_s,axial33_d; end interface
+interface diag
+ module procedure diagn_s,diagn_d,diagn_i,diagnn_s,diagnn_d,diagnn_i
+ end interface
+interface trace; module procedure trace_s,trace_d,trace_i; end interface
+interface identity; module procedure identity_i,identity3_i; end interface
+interface huarea; module procedure huarea_s,huarea_d; end interface
+interface sarea
+ module procedure sarea_s,sarea_d,dtarea_s,dtarea_d,dqarea_s,dqarea_d
+ end interface
+interface dlltoxy; module procedure dlltoxy_s,dlltoxy_d; end interface
+interface hav; module procedure hav_s, hav_d; end interface
+interface normalize;module procedure normalize_s,normalize_d; end interface
+interface gram
+ module procedure gram_s,gram_d,graml_d,plaingram_s,plaingram_d,rowgram
+ end interface
+interface rowops; module procedure rowops; end interface
+interface corral; module procedure corral; end interface
+interface rottoax; module procedure rottoax; end interface
+interface axtorot; module procedure axtorot; end interface
+interface spintoq; module procedure spintoq; end interface
+interface qtospin; module procedure qtospin; end interface
+interface rottoq; module procedure rottoq; end interface
+interface qtorot; module procedure qtorot; end interface
+interface axtoq; module procedure axtoq; end interface
+interface qtoax; module procedure qtoax; end interface
+interface setem; module procedure setem; end interface
+interface mulqq; module procedure mulqq; end interface
+interface expmat; module procedure expmat,expmatd,expmatdd; end interface
+interface zntay; module procedure zntay; end interface
+interface znfun; module procedure znfun; end interface
+interface ctoz; module procedure ctoz; end interface
+interface ztoc; module procedure ztoc,ztocd; end interface
+interface setmobius;module procedure setmobius,zsetmobius; end interface
+interface mobius; module procedure zmobius,cmobius; end interface
+interface mobiusi; module procedure zmobiusi; end interface
+
+contains
+
+!=============================================================================
+function absv_s(a)result(s)! [absv]
+!=============================================================================
+implicit none
+real(sp),dimension(:),intent(in):: a
+real(sp) :: s
+s=sqrt(dot_product(a,a))
+end function absv_s
+!=============================================================================
+function absv_d(a)result(s)! [absv]
+!=============================================================================
+implicit none
+real(dp),dimension(:),intent(in):: a
+real(dp) :: s
+s=sqrt(dot_product(a,a))
+end function absv_d
+
+!=============================================================================
+function normalized_s(a)result(b)! [normalized]
+!=============================================================================
+use jp_pietc_s, only: u0
+implicit none
+real(sp),dimension(:),intent(IN):: a
+real(sp),dimension(size(a)) :: b
+real(sp) :: s
+s=absv_s(a); if(s==u0)then; b=u0;else;b=a/s;endif
+end function normalized_s
+!=============================================================================
+function normalized_d(a)result(b)! [normalized]
+!=============================================================================
+use jp_pietc, only: u0
+implicit none
+real(dp),dimension(:),intent(IN):: a
+real(dp),dimension(size(a)) :: b
+real(dp) :: s
+s=absv_d(a); if(s==u0)then; b=u0;else;b=a/s;endif
+end function normalized_d
+
+!=============================================================================
+function orthogonalized_s(u,a)result(b)! [orthogonalized]
+!=============================================================================
+implicit none
+real(sp),dimension(:),intent(in):: u,a
+real(sp),dimension(size(u)) :: b
+real(sp) :: s
+! Note: this routine assumes u is already normalized
+s=dot_product(u,a); b=a-u*s
+end function orthogonalized_s
+!=============================================================================
+function orthogonalized_d(u,a)result(b)! [orthogonalized]
+!=============================================================================
+implicit none
+real(dp),dimension(:),intent(in):: u,a
+real(dp),dimension(size(u)) :: b
+real(dp) :: s
+! Note: this routine assumes u is already normalized
+s=dot_product(u,a); b=a-u*s
+end function orthogonalized_d
+
+!=============================================================================
+function cross_product_s(a,b)result(c)! [cross_product]
+!=============================================================================
+implicit none
+real(sp),dimension(3),intent(in):: a,b
+real(sp),dimension(3) :: c
+c(1)=a(2)*b(3)-a(3)*b(2); c(2)=a(3)*b(1)-a(1)*b(3); c(3)=a(1)*b(2)-a(2)*b(1)
+end function cross_product_s
+!=============================================================================
+function cross_product_d(a,b)result(c)! [cross_product]
+!=============================================================================
+implicit none
+real(dp),dimension(3),intent(in):: a,b
+real(dp),dimension(3) :: c
+c(1)=a(2)*b(3)-a(3)*b(2); c(2)=a(3)*b(1)-a(1)*b(3); c(3)=a(1)*b(2)-a(2)*b(1)
+end function cross_product_d
+!=============================================================================
+function triple_cross_product_s(u,v,w)result(x)! [cross_product]
+!=============================================================================
+! Deliver the triple-cross-product, x, of the
+! three 4-vectors, u, v, w, with the sign convention
+! that ordered, {u,v,w,x} form a right-handed quartet
+! in the generic case (determinant >= 0).
+!=============================================================================
+implicit none
+real(sp),dimension(4),intent(in ):: u,v,w
+real(sp),dimension(4) :: x
+!-----------------------------------------------------------------------------
+real(sp):: uv12,uv13,uv14,uv23,uv24,uv34
+!=============================================================================
+uv12=u(1)*v(2)-u(2)*v(1); uv13=u(1)*v(3)-u(3)*v(1); uv14=u(1)*v(4)-u(4)*v(1)
+ uv23=u(2)*v(3)-u(3)*v(2); uv24=u(2)*v(4)-u(4)*v(2)
+ uv34=u(3)*v(4)-u(4)*v(3)
+x(1)=-uv23*w(4)+uv24*w(3)-uv34*w(2)
+x(2)= uv13*w(4)-uv14*w(3) +uv34*w(1)
+x(3)=-uv12*w(4) +uv14*w(2)-uv24*w(1)
+x(4)= uv12*w(3)-uv13*w(2)+uv23*w(1)
+end function triple_cross_product_s
+!=============================================================================
+function triple_cross_product_d(u,v,w)result(x)! [cross_product]
+!=============================================================================
+implicit none
+real(dp),dimension(4),intent(in ):: u,v,w
+real(dp),dimension(4) :: x
+!-----------------------------------------------------------------------------
+real(dp):: uv12,uv13,uv14,uv23,uv24,uv34
+!=============================================================================
+uv12=u(1)*v(2)-u(2)*v(1); uv13=u(1)*v(3)-u(3)*v(1); uv14=u(1)*v(4)-u(4)*v(1)
+ uv23=u(2)*v(3)-u(3)*v(2); uv24=u(2)*v(4)-u(4)*v(2)
+ uv34=u(3)*v(4)-u(4)*v(3)
+x(1)=-uv23*w(4)+uv24*w(3)-uv34*w(2)
+x(2)= uv13*w(4)-uv14*w(3) +uv34*w(1)
+x(3)=-uv12*w(4) +uv14*w(2)-uv24*w(1)
+x(4)= uv12*w(3)-uv13*w(2)+uv23*w(1)
+end function triple_cross_product_d
+
+!=============================================================================
+function outer_product_s(a,b)result(c)! [outer_product]
+!=============================================================================
+implicit none
+real(sp),dimension(:), intent(in ):: a
+real(sp),dimension(:), intent(in ):: b
+real(sp),DIMENSION(size(a),size(b)):: c
+integer(spi) :: nb,i
+nb=size(b)
+do i=1,nb; c(:,i)=a*b(i); enddo
+end function outer_product_s
+!=============================================================================
+function outer_product_d(a,b)result(c)! [outer_product]
+!=============================================================================
+implicit none
+real(dp),dimension(:), intent(in ):: a
+real(dp),dimension(:), intent(in ):: b
+real(dp),dimension(size(a),size(b)):: c
+integer(spi) :: nb,i
+nb=size(b)
+do i=1,nb; c(:,i)=a*b(i); enddo
+end function outer_product_d
+!=============================================================================
+function outer_product_i(a,b)result(c)! [outer_product]
+!=============================================================================
+implicit none
+integer(spi),dimension(:), intent(in ):: a
+integer(spi),dimension(:), intent(in ):: b
+integer(spi),dimension(size(a),size(b)):: c
+integer(spi) :: nb,i
+nb=size(b)
+do i=1,nb; c(:,i)=a*b(i); enddo
+end function outer_product_i
+
+!=============================================================================
+function triple_product_s(a,b,c)result(tripleproduct)! [triple_product]
+!=============================================================================
+implicit none
+real(sp),dimension(3),intent(IN ):: a,b,c
+real(sp) :: tripleproduct
+tripleproduct=dot_product( cross_product(a,b),c )
+end function triple_product_s
+!=============================================================================
+function triple_product_d(a,b,c)result(tripleproduct)! [triple_product]
+!=============================================================================
+implicit none
+real(dp),dimension(3),intent(IN ):: a,b,c
+real(dp) :: tripleproduct
+tripleproduct=dot_product( cross_product(a,b),c )
+end function triple_product_d
+
+!=============================================================================
+function det_s(a)result(det)! [det]
+!=============================================================================
+use jp_pietc_s, only: u0
+implicit none
+real(sp),dimension(:,:),intent(IN ) :: a
+real(sp) :: det
+real(sp),dimension(size(a,1),size(a,1)):: b
+integer(spi) :: n,nrank
+n=size(a,1)
+if(n==3)then
+ det=triple_product(a(:,1),a(:,2),a(:,3))
+else
+ call gram(a,b,nrank,det)
+ if(nranku0
+implicit none
+real(sp),dimension(3),intent(IN ):: v1,v2,v3
+real(sp) :: area
+!- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+real(sp) :: s123,a1,a2,b,d1,d2,d3
+real(sp),dimension(3) :: u0,u1,u2,u3,x,y
+!=============================================================================
+area=zero
+u1=normalized(v1); u2=normalized(v2); u3=normalized(v3)
+s123=triple_product(u1,u2,u3)
+if(s123==zero)return
+
+d1=dot_product(u3-u2,u3-u2)
+d2=dot_product(u1-u3,u1-u3)
+d3=dot_product(u2-u1,u2-u1)
+
+! Triangle that is not degenerate. Cyclically permute, so side 3 is longest:
+if(d3u0
+implicit none
+real(dp),dimension(3),intent(IN ):: v1,v2,v3
+real(dp) :: area
+!- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+real(dp) :: s123,a1,a2,b,d1,d2,d3
+real(dp),dimension(3) :: u0,u1,u2,u3,x,y
+!=============================================================================
+area=zero
+u1=normalized(v1); u2=normalized(v2); u3=normalized(v3)
+s123=triple_product(u1,u2,u3)
+if(s123==zero)return
+
+d1=dot_product(u3-u2,u3-u2)
+d2=dot_product(u1-u3,u1-u3)
+d3=dot_product(u2-u1,u2-u1)
+
+! Triangle that is not degenerate. Cyclically permute, so side 3 is longest:
+if(d3nrank)exit
+ ab(k:m,k:n)=matmul( transpose(a(:,k:m)),b(:,k:n) )
+ ii =maxloc( abs( ab(k:m,k:n)) )+k-1
+ val=maxval( abs( ab(k:m,k:n)) )
+ if(val<=vcrit)then
+ nrank=k-1
+ exit
+ endif
+ i=ii(1)
+ j=ii(2)
+ tv=b(:,j)
+ b(:,j)=-b(:,k)
+ b(:,k)=tv
+ tv=a(:,i)
+ a(:,i)=-a(:,k)
+ a(:,k)=tv
+ w(k:n)=matmul( transpose(b(:,k:n)),tv )
+ b(:,k)=matmul(b(:,k:n),w(k:n) )
+ s=dot_product(b(:,k),b(:,k))
+ s=sqrt(s)
+ if(w(k)nrank)exit
+ ab(k:m,k:n)=matmul( transpose(a(:,k:m)),b(:,k:n) )
+ ii =maxloc( abs( ab(k:m,k:n)) )+k-1
+ val=maxval( abs( ab(k:m,k:n)) )
+ if(val<=vcrit)then
+ nrank=k-1
+ exit
+ endif
+ i=ii(1)
+ j=ii(2)
+ tv=b(:,j)
+ b(:,j)=-b(:,k)
+ b(:,k)=tv
+ tv=a(:,i)
+ a(:,i)=-a(:,k)
+ a(:,k)=tv
+ w(k:n)=matmul( transpose(b(:,k:n)),tv )
+ b(:,k)=matmul(b(:,k:n),w(k:n) )
+ s=dot_product(b(:,k),b(:,k))
+ s=sqrt(s)
+ if(w(k)nrank)exit
+ ab(k:m,k:n)=matmul( transpose(a(:,k:m)),b(:,k:n) )
+ ii =maxloc( abs( ab(k:m,k:n)) )+k-1
+ val=maxval( abs( ab(k:m,k:n)) )
+ if(val<=vcrit)then
+ nrank=k-1
+ exit
+ endif
+ i=ii(1)
+ j=ii(2)
+ tv=b(:,j)
+ b(:,j)=-b(:,k)
+ b(:,k)=tv
+ tv=a(:,i)
+ a(:,i)=-a(:,k)
+ a(:,k)=tv
+ w(k:n)=matmul( transpose(b(:,k:n)),tv )
+ b(:,k)=matmul(b(:,k:n),w(k:n) )
+ s=dot_product(b(:,k),b(:,k))
+ s=sqrt(s)
+ if(w(k)u0)then
+ ldet=ldet+log(s)
+ else
+ detsign=0
+ endif
+
+ b(:,k)=b(:,k)/s
+ do l=k,n
+ do j=l+1,n
+ s=dot_product(b(:,l),b(:,j))
+ b(:,j)=normalized( b(:,j)-b(:,l)*s )
+ enddo
+ enddo
+enddo
+end subroutine graml_d
+
+!=============================================================================
+subroutine plaingram_s(b,nrank)! [gram]
+!=============================================================================
+! A "plain" (unpivoted) version of Gram-Schmidt, for square matrices only.
+use jp_pietc_s, only: u0
+implicit none
+real(sp),dimension(:,:),intent(INOUT) :: b
+integer(spi), intent( OUT) :: nrank
+!- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+real(sp),parameter :: crit=1.e-5_sp
+real(sp) :: val,vcrit
+integer(spi) :: j,k,n
+!=============================================================================
+n=size(b,1); if(n/=size(b,2))stop 'In gram; matrix needs to be square'
+val=maxval(abs(b))
+nrank=0
+if(val==0)then
+ b=u0
+ return
+endif
+vcrit=val*crit
+do k=1,n
+ val=sqrt(dot_product(b(:,k),b(:,k)))
+ if(val<=vcrit)then
+ b(:,k:n)=u0
+ return
+ endif
+ b(:,k)=b(:,k)/val
+ nrank=k
+ do j=k+1,n
+ b(:,j)=b(:,j)-b(:,k)*dot_product(b(:,k),b(:,j))
+ enddo
+enddo
+end subroutine plaingram_s
+
+!=============================================================================
+subroutine plaingram_d(b,nrank)! [gram]
+!=============================================================================
+! A "plain" (unpivoted) version of Gram-Schmidt, for square matrices only.
+use jp_pietc, only: u0
+implicit none
+real(dp),dimension(:,:),intent(INOUT):: b
+integer(spi), intent( OUT):: nrank
+!- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+real(dp),parameter:: crit=1.e-9_dp
+real(dp) :: val,vcrit
+integer(spi) :: j,k,n
+!=============================================================================
+n=size(b,1); if(n/=size(b,2))stop 'In gram; matrix needs to be square'
+val=maxval(abs(b))
+nrank=0
+if(val==u0)then
+ b=u0
+ return
+endif
+vcrit=val*crit
+do k=1,n
+ val=sqrt(dot_product(b(:,k),b(:,k)))
+ if(val<=vcrit)then
+ b(:,k:n)=u0
+ return
+ endif
+ b(:,k)=b(:,k)/val
+ nrank=k
+ do j=k+1,n
+ b(:,j)=b(:,j)-b(:,k)*dot_product(b(:,k),b(:,j))
+ enddo
+enddo
+end subroutine plaingram_d
+
+!=============================================================================
+subroutine rowgram(m,n,a,ipiv,tt,b,rank)! [gram]
+!=============================================================================
+! Without changing (tall) rectangular input matrix a, perform pivoted gram-
+! Schmidt operations to orthogonalize the rows, until rows that remain become
+! negligible. Record the pivoting sequence in ipiv, and the row-normalization
+! in tt(j,j) and the row-orthogonalization in tt(i,j), for i>j. Note that
+! tt(i,j)=0 for i=n please'
+nepss=n*epss
+rank=n
+aa=a
+tt=u0
+do ii=1,n
+
+! At this stage, all rows less than ii are already orthonormalized and are
+! orthogonal to all rows at and beyond ii. Find the norms of these lower
+! rows and pivot the largest of them into position ii:
+ maxp=u0
+ maxi=ii
+ do i=ii,m
+ p(i)=dot_product(aa(i,:),aa(i,:))
+ if(p(i)>maxp)then
+ maxp=p(i)
+ maxi=i
+ endif
+ enddo
+ if(maxpu0,one=>u1,two=>u2
+implicit none
+real(dp),dimension(3,3),intent(IN ):: rot
+real(dp),dimension(0:3),intent(OUT):: q
+!------------------------------------------------------------------------------
+real(dp),dimension(3,3) :: t1,t2
+real(dp),dimension(3) :: u1,u2
+real(dp) :: gamma,gammah,s,ss
+integer(spi) :: i,j
+integer(spi),dimension(1):: ii
+!==============================================================================
+! construct the orthogonal matrix, t1, whose third row is the rotation axis
+! of rot:
+t1=rot; do i=1,3; t1(i,i)=t1(i,i)-1; u1(i)=dot_product(t1(i,:),t1(i,:)); enddo
+ii=maxloc(u1); j=ii(1); ss=u1(j)
+if(ss<1.e-16_dp)then
+ q=zero; q(0)=one; return
+endif
+t1(j,:)=t1(j,:)/sqrt(ss)
+if(j/=1)then
+ u2 =t1(1,:)
+ t1(1,:)=t1(j,:)
+ t1(j,:)=u2
+endif
+do i=2,3
+ t1(i,:)=t1(i,:)-dot_product(t1(1,:),t1(i,:))*t1(1,:)
+ u1(i)=dot_product(t1(i,:),t1(i,:))
+enddo
+if(u1(3)>u1(2))then
+ j=3
+else
+ j=2
+endif
+ss=u1(j)
+if(ss==zero)stop 'In rotov; invalid rot'
+if(j/=2)t1(2,:)=t1(3,:)
+t1(2,:)=t1(2,:)/sqrt(ss)
+
+! Form t1(3,:) as the cross product of t1(1,:) and t1(2,:)
+t1(3,1)=t1(1,2)*t1(2,3)-t1(1,3)*t1(2,2)
+t1(3,2)=t1(1,3)*t1(2,1)-t1(1,1)*t1(2,3)
+t1(3,3)=t1(1,1)*t1(2,2)-t1(1,2)*t1(2,1)
+
+! Project rot into the frame whose axes are the rows of t1:
+t2=matmul(t1,matmul(rot,transpose(t1)))
+
+! Obtain the rotation angle, gamma, implied by rot, and gammah=gamma/2:
+gamma=atan2(t2(2,1),t2(1,1)); gammah=gamma/two
+
+! Hence deduce coefficients (in the form of a real 4-vector) of one of the two
+! possible equivalent spinors:
+s=sin(gammah)
+q(0)=cos(gammah)
+q(1:3)=t1(3,:)*s
+end subroutine rottoq
+
+!==============================================================================
+subroutine qtorot(q,rot)! [qtorot]
+!==============================================================================
+! Go from quaternion to rotation matrix representations
+!==============================================================================
+implicit none
+real(dp),dimension(0:3),intent(IN ):: q
+real(dp),dimension(3,3),intent(OUT):: rot
+!=============================================================================
+call setem(q(0),q(1),q(2),q(3),rot)
+end subroutine qtorot
+
+!=============================================================================
+subroutine axtoq(v,q)! [axtoq]
+!=============================================================================
+! Go from an axial 3-vector to its equivalent quaternion
+!=============================================================================
+implicit none
+real(dp),dimension(3), intent(in ):: v
+real(dp),dimension(0:3),intent(out):: q
+!-----------------------------------------------------------------------------
+real(dp),dimension(3,3):: rot
+!=============================================================================
+call axtorot(v,rot)
+call rottoq(rot,q)
+end subroutine axtoq
+
+!=============================================================================
+subroutine qtoax(q,v)! [qtoax]
+!=============================================================================
+! Go from quaternion to axial 3-vector
+!=============================================================================
+implicit none
+real(dp),dimension(0:3),intent(in ):: q
+real(dp),dimension(3), intent(out):: v
+!-----------------------------------------------------------------------------
+real(dp),dimension(3,3):: rot
+!=============================================================================
+call qtorot(q,rot)
+call rottoax(rot,v)
+end subroutine qtoax
+
+!=============================================================================
+subroutine setem(c,d,e,g,r)! [setem]
+!=============================================================================
+implicit none
+real(dp), intent(IN ):: c,d,e,g
+real(dp),dimension(3,3),intent(OUT):: r
+!-----------------------------------------------------------------------------
+real(dp):: cc,dd,ee,gg,de,dg,eg,dc,ec,gc
+!=============================================================================
+cc=c*c; dd=d*d; ee=e*e; gg=g*g
+de=d*e; dg=d*g; eg=e*g
+dc=d*c; ec=e*c; gc=g*c
+r(1,1)=cc+dd-ee-gg; r(2,2)=cc-dd+ee-gg; r(3,3)=cc-dd-ee+gg
+r(2,3)=2*(eg-dc); r(3,1)=2*(dg-ec); r(1,2)=2*(de-gc)
+r(3,2)=2*(eg+dc); r(1,3)=2*(dg+ec); r(2,1)=2*(de+gc)
+end subroutine setem
+
+!=============================================================================
+function mulqq(a,b)result(c)! [mulqq]
+!=============================================================================
+! Multiply quaternions, a*b, assuming operation performed from right to left
+!=============================================================================
+implicit none
+real(dp),dimension(0:3),intent(IN ):: a,b
+real(dp),dimension(0:3) :: c
+!-------------------------------------------
+c(0)=a(0)*b(0) -a(1)*b(1) -a(2)*b(2) -a(3)*b(3)
+c(1)=a(0)*b(1) +a(1)*b(0) +a(2)*b(3) -a(3)*b(2)
+c(2)=a(0)*b(2) +a(2)*b(0) +a(3)*b(1) -a(1)*b(3)
+c(3)=a(0)*b(3) +a(3)*b(0) +a(1)*b(2) -a(2)*b(1)
+end function mulqq
+!=============================================================================
+subroutine expmat(n,a,b,detb)! [expmat]
+!=============================================================================
+! Evaluate the exponential, b, of a matrix, a, of degree n.
+! Apply the iterated squaring method, m times, to the approximation to
+! exp(a/(2**m)) obtained as a Taylor expansion of degree L
+! See Fung, T. C., 2004, Int. J. Numer. Meth. Engng, 59, 1273--1286.
+!=============================================================================
+use jp_pietc, only: u0,u1,u2,o2
+implicit none
+integer(spi), intent(IN ):: n
+real(dp),dimension(n,n),intent(IN ):: a
+real(dp),dimension(n,n),intent(OUT):: b
+real(dp), intent(OUT):: detb
+!-----------------------------------------------------------------------------
+integer(spi),parameter :: L=5
+real(dp),dimension(n,n):: c,p
+real(dp) :: t
+integer(spi) :: i,m
+!=============================================================================
+m=10+floor(log(u1+maxval(abs(a)))/log(u2))
+t=o2**m
+c=a*t
+p=c
+b=p
+do i=2,L
+ p=matmul(p,c)/i
+ b=b+p
+enddo
+do i=1,m
+ b=b*u2+matmul(b,b)
+enddo
+do i=1,n
+ b(i,i)=b(i,i)+u1
+enddo
+detb=u0; do i=1,n; detb=detb+a(i,i); enddo; detb=exp(detb)
+end subroutine expmat
+
+!=============================================================================
+subroutine expmatd(n,a,b,bd,detb,detbd)! [expmat]
+!=============================================================================
+! Like expmat, but for the 1st derivatives also.
+!=============================================================================
+use jp_pietc, only: u0,u1,u2,o2
+implicit none
+integer(spi), intent(IN ):: n
+real(dp),dimension(n,n), intent(IN ):: a
+real(dp),dimension(n,n), intent(OUT):: b
+real(dp),dimension(n,n,(n*(n+1))/2),intent(OUT):: bd
+real(dp), intent(OUT):: detb
+real(dp),dimension((n*(n+1))/2), intent(OUT):: detbd
+!-----------------------------------------------------------------------------
+integer(spi),parameter :: L=5
+real(dp),dimension(n,n) :: c,p
+real(dp),dimension(n,n,(n*(n+1))/2):: pd,cd
+real(dp) :: t
+integer(spi) :: i,j,k,m,n1
+!=============================================================================
+n1=(n*(n+1))*o2
+m=10+floor(log(u1+maxval(abs(a)))/log(u2))
+t=o2**m
+c=a*t
+p=c
+pd=u0
+do k=1,n
+ pd(k,k,k)=t
+enddo
+k=n
+do i=1,n-1
+ do j=i+1,n
+ k=k+1
+ pd(i,j,k)=t
+ pd(j,i,k)=t
+ enddo
+enddo
+if(k/=n1)stop 'In expmatd; n1 is inconsistent with n'
+cd=pd
+b=p
+bd=pd
+
+do i=2,L
+ do k=1,n1
+ pd(:,:,k)=(matmul(cd(:,:,k),p)+matmul(c,pd(:,:,k)))/i
+ enddo
+ p=matmul(c,p)/i
+ b=b+p
+ bd=bd+pd
+enddo
+do i=1,m
+ do k=1,n1
+ bd(:,:,k)=2*bd(:,:,k)+matmul(bd(:,:,k),b)+matmul(b,bd(:,:,k))
+ enddo
+ b=b*u2+matmul(b,b)
+enddo
+do i=1,n
+ b(i,i)=b(i,i)+u1
+enddo
+detb=u0; do i=1,n; detb=detb+a(i,i); enddo; detb=exp(detb)
+detbd=u0; do k=1,n; detbd(k)=detb; enddo
+end subroutine expmatd
+
+!=============================================================================
+subroutine expmatdd(n,a,b,bd,bdd,detb,detbd,detbdd)! [expmat]
+!=============================================================================
+! Like expmat, but for the 1st and 2nd derivatives also.
+!=============================================================================
+use jp_pietc, only: u0,u1,u2,o2
+implicit none
+integer(spi), intent(IN ):: n
+real(dp),dimension(n,n), intent(IN ):: a
+real(dp),dimension(n,n), intent(OUT):: b
+real(dp),dimension(n,n,(n*(n+1))/2), intent(OUT):: bd
+real(dp),dimension(n,n,(n*(n+1))/2,(n*(n+1))/2),intent(OUT):: bdd
+real(dp), intent(OUT):: detb
+real(dp),dimension((n*(n+1))/2), intent(OUT):: detbd
+real(dp),dimension((n*(n+1))/2,(n*(n+1))/2), intent(OUT):: detbdd
+!-----------------------------------------------------------------------------
+integer(spi),parameter :: L=5
+real(dp),dimension(n,n) :: c,p
+real(dp),dimension(n,n,(n*(n+1))/2) :: pd,cd
+real(dp),dimension(n,n,(n*(n+1))/2,(n*(n+1))/2):: pdd,cdd
+real(dp) :: t
+integer(spi) :: i,j,k,ki,kj,m,n1
+!=============================================================================
+n1=(n*(n+1))/2
+m=10+floor(log(u1+maxval(abs(a)))/log(u2))
+t=o2**m
+c=a*t
+p=c
+pd=u0
+pdd=u0
+do k=1,n
+ pd(k,k,k)=t
+enddo
+k=n
+do i=1,n-1
+ do j=i+1,n
+ k=k+1
+ pd(i,j,k)=t
+ pd(j,i,k)=t
+ enddo
+enddo
+if(k/=n1)stop 'In expmatd; n1 is inconsistent with n'
+cd=pd
+cdd=u0
+b=p
+bd=pd
+bdd=u0
+
+do i=2,L
+ do ki=1,n1
+ do kj=1,n1
+ pdd(:,:,ki,kj)=(matmul(cd(:,:,ki),pd(:,:,kj)) &
+ + matmul(cd(:,:,kj),pd(:,:,ki)) &
+ + matmul(c,pdd(:,:,ki,kj)))/i
+ enddo
+ enddo
+ do k=1,n1
+ pd(:,:,k)=(matmul(cd(:,:,k),p)+matmul(c,pd(:,:,k)))/i
+ enddo
+ p=matmul(c,p)/i
+ b=b+p
+ bd=bd+pd
+ bdd=bdd+pdd
+enddo
+do i=1,m
+ do ki=1,n1
+ do kj=1,n1
+ bdd(:,:,ki,kj)=u2*bdd(:,:,ki,kj) &
+ +matmul(bdd(:,:,ki,kj),b) &
+ +matmul(bd(:,:,ki),bd(:,:,kj)) &
+ +matmul(bd(:,:,kj),bd(:,:,ki)) &
+ +matmul(b,bdd(:,:,ki,kj))
+ enddo
+ enddo
+ do k=1,n1
+ bd(:,:,k)=2*bd(:,:,k)+matmul(bd(:,:,k),b)+matmul(b,bd(:,:,k))
+ enddo
+ b=b*u2+matmul(b,b)
+enddo
+do i=1,n
+ b(i,i)=b(i,i)+u1
+enddo
+detb=u0; do i=1,n; detb=detb+a(i,i); enddo; detb=exp(detb)
+detbd=u0; do k=1,n; detbd(k)=detb; enddo
+detbdd=u0; do ki=1,n; do kj=1,n; detbdd(ki,kj)=detb; enddo; enddo
+end subroutine expmatdd
+
+!=============================================================================
+subroutine zntay(n,z,zn)! [zntay]
+!=============================================================================
+use jp_pietc, only: u2
+implicit none
+integer(spi), intent(IN ):: n
+real(dp), intent(IN ):: z
+real(dp), intent(OUT):: zn
+!-----------------------------------------------------------------------------
+integer(spi),parameter:: ni=100
+real(dp),parameter :: eps0=1.e-16_dp
+integer(spi) :: i,i2,n2
+real(dp) :: t,eps,z2
+!=============================================================================
+z2=z*u2
+n2=n*2
+t=1
+do i=1,n
+ t=t/(i*2-1)
+enddo
+eps=t*eps0
+zn=t
+do i=1,ni
+ i2=i*2
+ t=t*z2/(i2*(i2+n2-1))
+ zn=zn+t
+ if(abs(t)u0)then
+ zn=cosh(rz2)
+ znd=sinh(rz2)/rz2
+ zndd=(zn-znd)/z2
+ znddd=(znd-u3*zndd)/z2
+ do i=1,n
+ i2p3=i*2+3
+ zn=znd
+ znd=zndd
+ zndd=znddd
+ znddd=(znd-i2p3*zndd)/z2
+ enddo
+ else
+ zn=cos(rz2)
+ znd=sin(rz2)/rz2
+ zndd=-(zn-znd)/z2
+ znddd=-(znd-u3*zndd)/z2
+ do i=1,n
+ i2p3=i*2+3
+ zn=znd
+ znd=zndd
+ zndd=znddd
+ znddd=-(znd-i2p3*zndd)/z2
+ enddo
+ endif
+endif
+end subroutine znfun
+
+!=============================================================================
+! Utility code for various Mobius transformations. If aa1,bb1,cc1,dd1 are
+! the coefficients for one transformation, and aa2,bb2,cc2,dd2 are the
+! coefficients for a second one, then the coefficients for the mapping
+! of a test point, zz, by aa1 etc to zw, followed by a mapping of zw, by
+! aa2 etc to zv, is equivalent to a single mapping zz-->zv by the transformatn
+! with coefficients aa3,bb3,cc3,dd3, such that, as 2*2 complex matrices:
+!
+! [ aa3, bb3 ] [ aa2, bb2 ] [ aa1, bb1 ]
+! [ ] = [ ] * [ ]
+! [ cc3, dd3 ] [ cc2, dd2 ] [ cc1, dd1 ] .
+!
+! Note that the determinant of these matrices is always +1
+!
+!=============================================================================
+subroutine ctoz(v, z,infz)! [ctoz]
+!=============================================================================
+use jp_pietc, only: u0,u1
+implicit none
+real(dp),dimension(3),intent(IN ):: v
+complex(dpc), intent(OUT):: z
+logical, intent(OUT):: infz
+!-----------------------------------------------------------------------------
+real(dp) :: rr,zzpi
+!=============================================================================
+infz=.false.
+z=cmplx(v(1),v(2),dpc)
+if(v(3)>u0)then
+ zzpi=u1/(u1+v(3))
+else
+ rr=v(1)**2+v(2)**2
+ infz=(rr==u0); if(infz)return ! <- The point is mapped to infinity (90S)
+ zzpi=(u1-v(3))/rr
+endif
+z=z*zzpi
+end subroutine ctoz
+
+!=============================================================================
+subroutine ztoc(z,infz, v)! [ztoc]
+!=============================================================================
+implicit none
+complex(dpc), intent(IN ):: z
+logical, intent(IN ):: infz
+real(dp),dimension(3),intent(OUT):: v
+!-----------------------------------------------------------------------------
+real(dp),parameter:: zero=0_dp,one=1_dp,two=2_dp
+real(dp) :: r,q,rs,rsc,rsbi
+!=============================================================================
+if(infz)then; v=(/zero,zero,-one/); return; endif
+r=real(z); q=aimag(z); rs=r*r+q*q
+rsc=one-rs
+rsbi=one/(one+rs)
+v(1)=two*rsbi*r
+v(2)=two*rsbi*q
+v(3)=rsc*rsbi
+end subroutine ztoc
+
+!=============================================================================
+subroutine ztocd(z,infz, v,vd)! [ztoc]
+!=============================================================================
+! The convention adopted for the complex derivative is that, for a complex
+! infinitesimal map displacement, delta_z, the corresponding infinitesimal
+! change of cartesian vector position is delta_v given by:
+! delta_v = Real(vd*delta_z).
+! Thus, by a kind of Cauchy-Riemann relation, Imag(vd)=v CROSS Real(vd).
+! THE DERIVATIVE FOR THE IDEAL POINT AT INFINITY HAS NOT BEEN CODED YET!!!
+!=============================================================================
+implicit none
+complex(dpc), intent(IN ):: z
+logical, intent(IN ):: infz
+real(dp),dimension(3), intent(OUT):: v
+complex(dpc),dimension(3),intent(OUT):: vd
+!-----------------------------------------------------------------------------
+real(dp),parameter :: zero=0_dp,one=1_dp,two=2_dp,four=4_dp
+real(dp) :: r,q,rs,rsc,rsbi,rsbis
+real(dp),dimension(3):: u1,u2
+integer(spi) :: i
+!=============================================================================
+if(infz)then; v=(/zero,zero,-one/); return; endif
+r=real(z); q=aimag(z); rs=r*r+q*q
+rsc=one-rs
+rsbi=one/(one+rs)
+rsbis=rsbi**2
+v(1)=two*rsbi*r
+v(2)=two*rsbi*q
+v(3)=rsc*rsbi
+u1(1)=two*(one+q*q-r*r)*rsbis
+u1(2)=-four*r*q*rsbis
+u1(3)=-four*r*rsbis
+u2=cross_product(v,u1)
+do i=1,3
+ vd(i)=cmplx(u1(i),-u2(i),dpc)
+enddo
+end subroutine ztocd
+
+!============================================================================
+subroutine setmobius(xc0,xc1,xc2, aa,bb,cc,dd)! [setmobius]
+!============================================================================
+! Find the Mobius transformation complex coefficients, aa,bb,cc,dd,
+! with aa*dd-bb*cc=1, for a standard (north-)polar stereographic transformation
+! that takes cartesian point, xc0 to the north pole, xc1 to (lat=0,lon=0),
+! xc2 to the south pole (=complex infinity).
+!============================================================================
+implicit none
+real(dp),dimension(3),intent(IN ):: xc0,xc1,xc2
+complex(dpc), intent(OUT):: aa,bb,cc,dd
+!----------------------------------------------------------------------------
+real(dp),parameter:: zero=0_dp,one=1_dp
+logical :: infz0,infz1,infz2
+complex(dpc) :: z0,z1,z2,z02,z10,z21
+!============================================================================
+call ctoz(xc0,z0,infz0)
+call ctoz(xc1,z1,infz1)
+call ctoz(xc2,z2,infz2)
+z21=z2-z1
+z02=z0-z2
+z10=z1-z0
+
+if( (z0==z1.and.infz0.eqv.infz1).or.&
+ (z1==z2.and.infz1.eqv.infz2).or.&
+ (z2==z0.and.infz2.eqv.infz0)) &
+ stop 'In setmobius; anchor points must be distinct'
+
+if(infz2 .or. (.not.infz0 .and. abs(z0)= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km_in,1:imax,nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_S(:,i,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km_in,1:imax,nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j)=W(:,i,jmax-nby+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+
+ end if
+!
+! RECEIVE boundaries from NORTH and SOUTH
+!
+
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( rBuf_N(1:km_in,1:imax,nby), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( rBuf_S(1:km_in,1:imax,nby), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ end if
+!
+! Assign received values from NORTH and SOUTH
+!
+! From SOUTH
+
+ if(lsouth) then
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j)=W(:,i,nby+1-j)
+ end do
+ end do
+
+ else
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j)=rBuf_S(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+! --- from NORTH ---
+
+ if( lnorth) then
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j)=W(:,i,jmax+1-j)
+ enddo
+ enddo
+
+ else
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j)=rBuf_N(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!----------------------------------------------------------------------
+!
+! SEND extended boundaries toward WEST and EAST
+!
+
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_W(:,i,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_E(:,i,j) = W(:,imax-nbx+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE boundaries from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( rBuf_E(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+ allocate( rBuf_W(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ end if
+
+
+!
+! Assign received values from EAST and WEST
+!
+
+! From west
+
+ if(lwest) then
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,-nbx+i,j)= W(:,nbx+1-i,j)
+ end do
+ end do
+
+ else
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,-nbx+i,j)= rBuf_W(:,i,j)
+ enddo
+ enddo
+
+
+ endif
+
+! From east
+
+ if(least) then
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax+i,j)=W(:,imax+1-i,j)
+ end do
+ end do
+
+ else
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax+i,j)=rBuf_E(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+
+ if( itarg_s >= 0 ) then
+ deallocate( rBuf_S, stat = iderr)
+ end if
+ if( itarg_n >= 0 ) then
+ deallocate( rBuf_N, stat = iderr)
+ end if
+ if( itarg_e >= 0 ) then
+ deallocate( rBuf_E, stat = iderr)
+ end if
+ if( itarg_w >= 0 ) then
+ deallocate( rBuf_W, stat = iderr)
+ end if
+
+!
+! DEALLOCATE sBufferes
+!
+
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_S, stat = ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_N, stat = ierr )
+ end if
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_E, stat = ierr )
+ end if
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_W, stat = ierr )
+ end if
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine boco_2d_g1
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine boco_2d_gh &
+!**********************************************************************!
+! !
+! Side sending subroutine: !
+! Supplies (nbx,nby) lines of halos in (x,y) directions assuming !
+! mirror boundary conditions. Version for high generations !
+! !
+! - offset version - !
+! !
+!**********************************************************************!
+(this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_N,sBuf_E,sBuf_S,sBuf_W &
+ ,rBuf_N,rBuf_E,rBuf_S,rBuf_W
+
+integer(i_kind) itarg_n,itarg_s,itarg_w,itarg_e,imax,jmax
+logical:: lwest,least,lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,l,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax,ndatay
+integer(i_kind) g_ind,g
+logical l_sidesend
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Limit communications to selected number of generations
+!
+
+ if(mygen_min <= my_hgen .and. my_hgen <= mygen_max) then
+ g_ind=2
+ g = my_hgen
+ l_sidesend=.true.
+ else
+ l_sidesend=.false.
+ endif
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+FILT_GRID: if(l_sidesend) then
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+!
+! from mg_domain
+!
+ itarg_n = Fitarg_n(g_ind)
+ itarg_s = Fitarg_s(g_ind)
+ itarg_w = Fitarg_w(g_ind)
+ itarg_e = Fitarg_e(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+
+ if(least) then
+ imax = Fimax_in(g)
+ else
+ imax = im_in ! << Note that is not necesseraly im from
+ endif ! mg_parameter. Could be also imL >>>
+ if(lnorth) then
+ jmax = Fjmax_in(g)
+ else
+ jmax = jm_in
+ endif
+
+
+!-----------------------------------------------------------------------
+ ndatay = km_in*imax*nby
+ ndatax = km_in*(jmax+2*nby)*nbx
+
+
+!
+! SEND boundaries to SOUTH and NORTH
+!
+
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km_in,1:imax,nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_S(:,i,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km_in,1:imax,nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j)=W(:,i,jmax-nby+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+
+ end if
+!
+! RECEIVE boundaries from NORTH and SOUTH
+!
+
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( rBuf_N(1:km_in,1:imax,nby), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( rBuf_S(1:km_in,1:imax,nby), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ end if
+
+!
+! Assign received values from NORTH and SOUTH
+!
+
+
+! From south
+
+ if(lsouth) then
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j)=W(:,i,nby+1-j)
+ end do
+ end do
+
+ else
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j)=rBuf_S(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+! --- from NORTH ---
+
+ if( lnorth) then
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j)=W(:,i,jmax+1-j)
+ enddo
+ enddo
+
+ else
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j)=rBuf_N(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!
+! SEND extended boundaries to WEST and EASTH
+!
+
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_W(:,i,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_E(:,i,j) = W(:,imax-nbx+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE extended boundaries from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( rBuf_E(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+ allocate( rBuf_W(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ end if
+
+!
+! Assign received values from WEST and EAST
+!
+
+! From west
+
+ if(lwest) then
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,-nbx+i,j)= W(:,nbx+1-i,j)
+ end do
+ end do
+
+ else
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,-nbx+i,j)= rBuf_W(:,i,j)
+ enddo
+ enddo
+
+
+ endif
+
+! From east
+
+ if(least) then
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax+i,j)=W(:,imax+1-i,j)
+ end do
+ end do
+
+ else
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax+i,j)=rBuf_E(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+ if( itarg_w >= 0 ) then
+ deallocate( rBuf_W, stat = iderr)
+ end if
+ if( itarg_e >= 0 ) then
+ deallocate( rBuf_E, stat = iderr)
+ end if
+ if( itarg_s >= 0 ) then
+ deallocate( rBuf_S, stat = iderr)
+ end if
+ if( itarg_n >= 0 ) then
+ deallocate( rBuf_N, stat = iderr)
+ end if
+
+!
+! DEALLOCATE sBufferes
+!
+
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_W, stat = ierr )
+ end if
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_E, stat = ierr )
+ end if
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_S, stat = ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_N, stat = ierr )
+ end if
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+ endif FILT_GRID
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine boco_2d_gh
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocoT_2d_g1 &
+!***********************************************************************
+! !
+! Adjoint of side sending subroutine: !
+! Supplies (nbx,nby) lines of halos in (x,y) directions, including !
+! values at the edges of the subdomains and assuming mirror boundary !
+! conditions just for generation 1 !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,km_in,im_in,jm_in,nbx,nby)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby
+real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_N,sBuf_E,sBuf_S,sBuf_W &
+ ,rBuf_N,rBuf_E,rBuf_S,rBuf_W
+
+integer(i_kind) itarg_n,itarg_s,itarg_w,itarg_e,imax,jmax
+logical lwest,least,lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,L,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax,ndatay
+logical l_sidesend
+integer(i_kind) g_ind,g,k
+!-----------------------------------------------------------------------
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!
+! Limit comminications to selected number of generations
+!
+
+
+ g_ind=1
+!
+! from mg_domain
+!
+ itarg_n = Fitarg_n(g_ind)
+ itarg_s = Fitarg_s(g_ind)
+ itarg_w = Fitarg_w(g_ind)
+ itarg_e = Fitarg_e(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+ imax = im_in
+ jmax = jm_in
+
+
+!----------------------------------------------------------------------
+ ndatax =km_in*(jmax+2*nby)*nbx
+ ndatay =km_in*imax*nby
+!
+! SEND extended halos toward WEST and EAST
+!
+
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_W(:,i,j) = W(:,-nbx+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_E(:,i,j) = W(:,imax+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE extended halos from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+
+ allocate( rBuf_E(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+
+ allocate( rBuf_W(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+
+ end if
+
+!
+! Assign received halos from WEST and EAST to interrior of domains
+!
+
+! From west
+
+ if(lwest) then
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,i,j)= W(:,i,j)+W(:,1-i,j)
+ end do
+ end do
+ else
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,i,j)= W(:,i,j)+rBuf_W(:,i,j)
+ end do
+ end do
+ endif
+
+! From east
+
+ if(least) then
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax-nbx+i,j)= W(:,imax-nbx+i,j)+W(:,imax+1+nbx-i,j)
+ end do
+ end do
+ else
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax-nbx+i,j)= W(:,imax-nbx+i,j)+rBuf_E(:,i,j)
+ end do
+ end do
+ endif
+
+!
+! SEND boundaries SOUTH and NORTH
+!
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km_in,1:imax,1:nby), stat = iaerr )
+
+ do j=1-nby,0
+ do i=1,imax
+ sBuf_S(:,i,j+nby) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km_in,1:imax,1:nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j)=W(:,i,jmax+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+
+ end if
+
+!
+! RECEIVE boundaries from NORTH and SOUTH
+!
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+
+ allocate( rBuf_N(1:km_in,1:imax,1:nby), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+
+ allocate( rBuf_S(1:km_in,1:imax,1:nby), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+
+ end if
+
+!
+! ASSIGN received values from SOUTH and NORTH
+!
+
+! From south
+
+ if(lsouth) then
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j)= W(:,i,j)+W(:,i,1-j)
+ end do
+ end do
+ else
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j)= W(:,i,j)+rBuf_S(:,i,j)
+ end do
+ end do
+ endif
+
+! From north
+
+ if(lnorth) then
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j)= W(:,i,jmax-nby+j)+W(:,i,jmax+1+nby-j)
+ enddo
+ enddo
+ else
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j)= W(:,i,jmax-nby+j)+rBuf_N(:,i,j)
+ enddo
+ enddo
+ endif
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+
+ deallocate( rBuf_W, stat = iderr)
+ deallocate( rBuf_E, stat = iderr)
+ deallocate( rBuf_S, stat = iderr)
+ deallocate( rBuf_N, stat = iderr)
+
+!
+! DEALLOCATE sBufferes
+!
+
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ end if
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ end if
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ end if
+
+
+!-----------------------------------------------------------------------
+endsubroutine bocoT_2d_g1
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocoT_2d_gh &
+!***********************************************************************
+! !
+! Supply n-lines inside of domains, including edges, with halos from !
+! the surrounding domains. Assume mirror boundary conditions at the !
+! boundaries of the domain. For high multigrid generations. !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_N,sBuf_E,sBuf_S,sBuf_W &
+ ,rBuf_N,rBuf_E,rBuf_S,rBuf_W
+integer(i_kind) itarg_n,itarg_s,itarg_w,itarg_e,imax,jmax
+logical lwest,least,lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,L,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax,ndatay
+logical l_sidesend
+integer(i_kind) g_ind,g,k
+!-----------------------------------------------------------------------
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!
+! Limit comminications to selected number of generations
+!
+
+
+ if(mygen_min <= my_hgen .and. my_hgen <= mygen_max) then
+ g_ind=2
+ g = my_hgen
+ l_sidesend=.true.
+ else
+ l_sidesend=.false.
+ endif
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+FILT_GRID: if(l_sidesend) then
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!
+! from mg_domain
+!
+ itarg_n = Fitarg_n(g_ind)
+ itarg_s = Fitarg_s(g_ind)
+ itarg_w = Fitarg_w(g_ind)
+ itarg_e = Fitarg_e(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+
+ if(least) then
+ imax = Fimax_in(g)
+ else
+ imax = im_in ! << Note that is not necesseraly im from
+ endif ! mg_parameter. Could be also imL >>>
+ if(lnorth) then
+ jmax = Fjmax_in(g)
+ else
+ jmax = jm_in
+ endif
+
+
+!----------------------------------------------------------------------
+ ndatax =km_in*(jmax+2*nby)*nbx
+ ndatay =km_in*imax*nby
+
+!
+! SEND extended halos toward WEST and EAST
+!
+
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_W(:,i,j) = W(:,-nbx+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_E(:,i,j) = W(:,imax+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE extended halos from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( rBuf_E(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+ allocate( rBuf_W(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ end if
+!
+! Assign received values from WEST and EAST
+!
+
+! From west
+
+ if(lwest) then
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,i,j)= W(:,i,j)+W(:,1-i,j)
+ end do
+ end do
+ else
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,i,j)= W(:,i,j)+rBuf_W(:,i,j)
+ end do
+ end do
+ endif
+
+! From east
+
+ if(least) then
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax-nbx+i,j)= W(:,imax-nbx+i,j)+W(:,imax+1+nbx-i,j)
+ end do
+ end do
+ else
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax-nbx+i,j)= W(:,imax-nbx+i,j)+rBuf_E(:,i,j)
+ end do
+ end do
+ endif
+
+!
+! SEND halos toward SOUTH and NORTH
+!
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km_in,1:imax,1:nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_S(:,i,j) = W(:,i,-nby+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km_in,1:imax,1:nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j)=W(:,i,jmax+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+
+ end if
+
+!
+! RECEIVE halos from NORTH and SOUTH
+!
+!
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+
+ allocate( rBuf_N(1:km_in,1:imax,1:nby), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+
+ allocate( rBuf_S(1:km_in,1:imax,1:nby), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+
+ end if
+
+!
+! Assign received values from SOUTH and NORTH
+!
+
+! From south
+
+ if(lsouth) then
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j)= W(:,i,j)+W(:,i,1-j)
+ end do
+ end do
+ else
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j)= W(:,i,j)+rBuf_S(:,i,j)
+ end do
+ end do
+ endif
+
+! From north
+
+ if(lnorth) then
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j)= W(:,i,jmax-nby+j)+W(:,i,jmax+1+nby-j)
+ enddo
+ enddo
+ else
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j)= W(:,i,jmax-nby+j)+rBuf_N(:,i,j)
+ enddo
+ enddo
+ endif
+
+!-----------------------------------------------------------------------
+
+! DEALLOCATE rBufferes
+
+ deallocate( rBuf_W, stat = iderr)
+ deallocate( rBuf_E, stat = iderr)
+ deallocate( rBuf_S, stat = iderr)
+ deallocate( rBuf_N, stat = iderr)
+
+! DEALLOCATE sBufferes
+
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ end if
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ end if
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ end if
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+ endif FILT_GRID
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine bocoT_2d_gh
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine boco_3d_g1 &
+!**********************************************************************!
+! !
+! Side sending subroutine: !
+! Supplies (nbx,nby) lines of halos in (x,y) directions assuming !
+! mirror boundary conditions. Version for generation 1 !
+! !
+! - offset version - !
+! !
+!**********************************************************************!
+(this,W,km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz,Fimax_in,Fjmax_in)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz
+real(r_kind),dimension(km3_in,1-nbx:im_in+nbx,1-nby:jm_in+nby,1-nbz:Lm_in+nbz) &
+ ,intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+
+real(r_kind), allocatable, dimension(:,:,:,:):: &
+ sBuf_N,sBuf_E,sBuf_S,sBuf_W &
+ ,rBuf_N,rBuf_E,rBuf_S,rBuf_W
+
+integer(i_kind) itarg_n,itarg_s,itarg_w,itarg_e,imax,jmax
+logical:: lwest,least,lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,l,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax,ndatay
+integer(i_kind) g_ind,g
+logical l_sidesend
+!-----------------------------------------------------------------------
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!
+! Limit communications to generation one
+!
+ g_ind=1
+
+ itarg_n = Fitarg_n(g_ind)
+ itarg_s = Fitarg_s(g_ind)
+ itarg_w = Fitarg_w(g_ind)
+ itarg_e = Fitarg_e(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+ imax = im_in
+ jmax = jm_in
+
+!-----------------------------------------------------------------------
+ ndatay = km3_in*imax*nby*Lm
+ ndatax = km3_in*(jmax+2*nby)*nbx*Lm_in
+
+
+!
+! SEND boundaries toward SOUTH and NORTH
+!
+
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km3_in,1:imax,nby,1:Lm_in), stat = iaerr )
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ sBuf_S(:,i,j,L) = W(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km3_in,1:imax,nby,1:Lm_in), stat = iaerr )
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j,L)=W(:,i,jmax-nby+j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+
+ end if
+!
+! RECEIVE boundaries from NORTH and SOUTH
+!
+
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( rBuf_N(1:km3_in,1:imax,nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( rBuf_S(1:km3_in,1:imax,nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ end if
+!
+! Assign received values from NORTH and SOUTH
+!
+
+! --- from NORTH ---
+
+ if( lnorth) then
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j,L)=W(:,i,jmax+1-j,L)
+ enddo
+ enddo
+ enddo
+
+ else
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j,L)=rBuf_N(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ endif
+
+! From south
+
+ if(lsouth) then
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j,L)=W(:,i,nby+1-j,L)
+ end do
+ end do
+ end do
+
+ else
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j,L)=rBuf_S(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ endif
+
+!
+! SEND extended boundaries toward WEST and EAST
+!
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km3_in,nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_W(:,i,j,L) = W(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km3_in,nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_E(:,i,j,L) = W(:,imax-nbx+i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE boundaries WEST and EAST
+!
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+ allocate( rBuf_W(1:km3_in,nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ end if
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( rBuf_E(1:km3_in,nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+!
+! Assign received values from EAST and WEST
+!
+! From west
+
+ if(lwest) then
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,-nbx+i,j,L)= W(:,nbx+1-i,j,L)
+ end do
+ end do
+ end do
+
+ else
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,-nbx+i,j,L)= rBuf_W(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+
+ endif
+
+! From east
+
+ if(least) then
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax+i,j,L)=W(:,imax-i,j,L)
+ end do
+ end do
+ end do
+
+ else
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax+i,j,L)=rBuf_E(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ endif
+
+!------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+
+ if( itarg_w >= 0 ) then
+ deallocate( rBuf_W, stat = iderr)
+ end if
+ if( itarg_e >= 0 ) then
+ deallocate( rBuf_E, stat = iderr)
+ end if
+ if( itarg_s >= 0 ) then
+ deallocate( rBuf_S, stat = iderr)
+ end if
+ if( itarg_n >= 0 ) then
+ deallocate( rBuf_N, stat = iderr)
+ end if
+
+!
+! DEALLOCATE sBufferes
+!
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_W, stat = ierr )
+ end if
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_E, stat = ierr )
+ end if
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_S, stat = ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_N, stat = ierr )
+ end if
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+
+!-----------------------------------------------------------------------
+endsubroutine boco_3d_g1
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine boco_3d_gh &
+!**********************************************************************!
+
+! Side sending subroutine: !
+! Supplies (nbx,nby) lines of halos in (x,y) directions assuming !
+! mirror boundary conditions. Version for high generations !
+! !
+! - offset version - !
+! !
+!**********************************************************************!
+(this,W,km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz,mygen_min,mygen_max
+real(r_kind),dimension(km3_in,1-nbx:im_in+nbx,1-nby:jm_in+nby,1-nbz:Lm_in+nbz) &
+ ,intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+
+real(r_kind), allocatable, dimension(:,:,:,:):: &
+ sBuf_N,sBuf_E,sBuf_S,sBuf_W &
+ ,rBuf_N,rBuf_E,rBuf_S,rBuf_W
+
+integer(i_kind) itarg_n,itarg_s,itarg_w,itarg_e,imax,jmax
+logical:: lwest,least,lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,l,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax,ndatay
+integer(i_kind) g_ind,g
+logical l_sidesend
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Limit communications to selected number of generations
+!
+ if(mygen_min <= my_hgen .and. my_hgen <= mygen_max) then
+ g_ind=2
+ g = my_hgen
+ l_sidesend=.true.
+ else
+ l_sidesend=.false.
+ endif
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+FILT_GRID: if(l_sidesend) then
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+!
+! from mg_domain
+!
+ itarg_n = Fitarg_n(g_ind)
+ itarg_s = Fitarg_s(g_ind)
+ itarg_w = Fitarg_w(g_ind)
+ itarg_e = Fitarg_e(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+ if(least) then
+ imax = Fimax_in(g)
+ else
+ imax = im_in ! << Note that is not necesseraly im from
+ endif ! mg_parameter. Could be also imL >>>
+ if(lnorth) then
+ jmax = Fjmax_in(g)
+ else
+ jmax = jm_in
+ endif
+
+
+!-----------------------------------------------------------------------
+ ndatay = km3_in*imax*nby*Lm
+ ndatax = km3_in*(jmax+2*nby)*nbx*Lm
+
+!
+! SEND boundaries to SOUTH and NORTH
+!
+
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km3_in,1:imax,nby,1:Lm_in), stat = iaerr )
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ sBuf_S(:,i,j,L) = W(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km3_in,1:imax,nby,1:Lm_in), stat = iaerr )
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j,L)=W(:,i,jmax-nby+j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+
+ end if
+!
+! RECEIVE boundaries from SOUTH and NORTH
+!
+
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( rBuf_N(1:km3_in,1:imax,nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( rBuf_S(1:km3_in,1:imax,nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ end if
+
+!TEST
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_N, stat = ierr )
+ end if
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_S, stat = ierr )
+ end if
+!TEST
+
+!
+! Assign received values from NORTH and SOUTH
+!
+
+! --- from NORTH ---
+
+ if( lnorth) then
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j,L)=W(:,i,jmax+1-j,L)
+ enddo
+ enddo
+ enddo
+
+ else
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j,L)=rBuf_N(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ endif
+
+! From south
+
+ if(lsouth) then
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j,L)=W(:,i,nby+1-j,L)
+ end do
+ end do
+ end do
+
+ else
+
+ do L=1,Lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j,L)=rBuf_S(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ endif
+
+!TEST
+ if( itarg_n >= 0 ) then
+ deallocate( rBuf_N, stat = iderr)
+ endif
+
+ if( itarg_s >= 0 ) then
+ deallocate( rBuf_S, stat = iderr)
+ endif
+!TEST
+
+
+!
+! SEND extended boundaries to WEST and EAST
+!
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km3_in,nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_W(:,i,j,L) = W(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km3_in,nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_E(:,i,j,L) = W(:,imax-nbx+i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE boundaries from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( rBuf_E(1:km3_in,nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+ allocate( rBuf_W(1:km3_in,nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+!
+! Deallocate send bufferes from EAST and WEST
+!
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_E, stat = ierr )
+ end if
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_W, stat = ierr )
+ end if
+
+!
+! Assign received values from WEST and EAST
+!
+! From west
+
+ if(lwest) then
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,-nbx+i,j,L)= W(:,nbx+1-i,j,L)
+ end do
+ end do
+ end do
+
+ else
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,-nbx+i,j,L)= rBuf_W(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+
+ endif
+
+! From east
+
+ if(least) then
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax+i,j,L)=W(:,imax+1-i,j,L)
+ end do
+ end do
+ end do
+
+ else
+
+ do L=1,Lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax+i,j,L)=rBuf_E(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ endif
+
+!
+! Set up mirror b.c. at the bottom and top of domain
+!
+ do L=1,nbz
+ W(:,:,:,1-L )=W(:,:,:, 1+L)
+ W(:,:,:,LM+L)=W(:,:,:,LM-L)
+ end do
+
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+
+ if( itarg_w >= 0 ) then
+ deallocate( rBuf_W, stat = iderr)
+ endif
+ if( itarg_e >= 0 ) then
+ deallocate( rBuf_E, stat = iderr)
+ endif
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+ endif FILT_GRID
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine boco_3d_gh
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocoT_3d_g1 &
+!***********************************************************************
+! *
+! Supply n-lines inside of domains, including edges, with halos from *
+! the surrounding domains. Assume mirror boundary conditions at the *
+! boundaries of the domain *
+! !
+! - offset version - !
+! *
+!***********************************************************************
+(this,W,km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz,Fimax_in,Fjmax_in)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz
+real(r_kind), dimension(km3_in,1-nbx:im_in+nbx,1-nby:jm_in+nby,1-nbz:Lm_in+nbz) &
+ ,intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+
+real(r_kind), allocatable, dimension(:,:,:,:):: &
+ sBuf_N,sBuf_E,sBuf_S,sBuf_W &
+ ,rBuf_N,rBuf_E,rBuf_S,rBuf_W
+
+integer(i_kind) itarg_n,itarg_s,itarg_w,itarg_e,imax,jmax
+logical lwest,least,lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,L,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax,ndatay
+logical l_sidesend
+integer(i_kind) g_ind,g,k
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Limit comminications to selected number of generations
+!
+
+ g_ind=1
+
+!
+! from mg_domain
+!
+ itarg_n = Fitarg_n(g_ind)
+ itarg_s = Fitarg_s(g_ind)
+ itarg_w = Fitarg_w(g_ind)
+ itarg_e = Fitarg_e(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+
+ imax = im
+ jmax = jm
+
+!----------------------------------------------------------------------
+ ndatax =km3_in*(jmax+2*nby)*nbx *Lm_in
+ ndatay =km3_in*imax*nby *Lm_in
+
+!
+! SEND extended halos toward WEST and EAST
+!
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km3_in,1:nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+
+ do L=Lm_in,1,-1
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_W(:,i,j,L) = W(:,-nbx+i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km3_in,1:nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+
+ do L=Lm_in,1,-1
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_E(:,i,j,L) = W(:,imax+i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+
+ end if
+!
+! RECEIVE extended halos from EAST and WEST
+!
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+
+ allocate( rBuf_E(1:km3_in,1:nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+
+ allocate( rBuf_W(1:km3_in,1:nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+
+ end if
+!
+! Assign received extended halos from WEST and EAST to interior of domains
+!
+
+! From west
+
+ if(lwest) then
+ do L=1,lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,i,j,L)= W(:,i,j,L)+W(:,1-i,j,L)
+ end do
+ end do
+ end do
+ else
+ do L=1,lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,i,j,L)= W(:,i,j,L)+rBuf_W(:,i,j,L)
+ end do
+ end do
+ end do
+ endif
+
+! From east
+
+ if(least) then
+ do L=1,lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax-nbx+i,j,L)= W(:,imax-nbx+i,j,L)+W(:,imax+nbx-i,j,L)
+ end do
+ end do
+ end do
+ else
+ do L=1,lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax-nbx+i,j,L)= W(:,imax-nbx+i,j,L)+rBuf_E(:,i,j,L)
+ end do
+ end do
+ end do
+ endif
+
+!
+! Send halos SOUTH and NORTH
+!
+
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km3_in,1:imax,1:nby,1:Lm_in), stat = iaerr )
+
+ do L=Lm_in,1,-1
+ do j=1-nby,0
+ do i=1,imax
+ sBuf_S(:,i,j+nby,L) = W(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km3_in,1:imax,1:nby,1:Lm_in), stat = iaerr )
+
+ do L=Lm_in,1,-1
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j,L)=W(:,i,jmax+j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+
+ end if
+
+
+!
+! RECEIVE boundaries from NORTH and SOUTH
+!
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+
+ allocate( rBuf_N(1:km3_in,1:imax,1:nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+
+ allocate( rBuf_S(1:km3_in,1:imax,1:nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+
+ end if
+
+!
+! Assign received values from SOUTH and NORTH
+!
+
+! From south
+
+ if(lsouth) then
+ do L=1,lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j,L)= W(:,i,j,L)+W(:,i,1-j,L)
+ end do
+ end do
+ end do
+ else
+ do L=1,lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j,L)= W(:,i,j,L)+rBuf_S(:,i,j,L)
+ end do
+ end do
+ end do
+ endif
+
+! From north
+
+ if(lnorth) then
+ do L=1,lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j,L)= W(:,i,jmax-nby+j,L)+W(:,i,jmax+nby-j,L)
+ enddo
+ enddo
+ enddo
+ else
+ do L=1,lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j,L)= W(:,i,jmax-nby+j,L)+rBuf_N(:,i,j,L)
+ enddo
+ enddo
+ enddo
+ endif
+
+!----------------------------------------------------------------------
+!
+! Set up mirror b.c. at the bottom and top of domain
+!
+ do L=1,nbz
+ W(:,:,:,1+L )=W(:,:,:, 1+L)+W(:,:,:, 1-L)
+ W(:,:,:,LM-L)=W(:,:,:,LM-L)+W(:,:,:,LM+L)
+ end do
+
+
+!----------------------------------------------------------------------
+!
+! DEALLOCATE sBufferes
+!
+
+
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_W, stat = ierr )
+ end if
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_E, stat = ierr )
+ end if
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_S, stat = ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_N, stat = ierr )
+ end if
+
+
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+
+ if( itarg_w >= 0 ) then
+ deallocate( rBuf_W, stat = iderr)
+ endif
+ if( itarg_e >= 0 ) then
+ deallocate( rBuf_E, stat = iderr)
+ endif
+ if( itarg_s >= 0 ) then
+ deallocate( rBuf_S, stat = iderr)
+ endif
+ if( itarg_n >= 0 ) then
+ deallocate( rBuf_N, stat = iderr)
+ endif
+
+
+!-----------------------------------------------------------------------
+endsubroutine bocoT_3d_g1
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocoT_3d_gh &
+!***********************************************************************
+! *
+! Supply n-lines inside of domains, including edges, with halos from *
+! the surrounding domains. Assume mirror boundary conditions at the *
+! boundaries of the domain *
+! !
+! - offset version - !
+! *
+!***********************************************************************
+(this,W,km_in,im_in,jm_in,Lm_in,nbx,nby,nbz,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,Lm_in,nbx,nby,nbz,mygen_min,mygen_max
+real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby,1-nbz:Lm_in+nbz) &
+ ,intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:,:):: &
+ sBuf_N,sBuf_E,sBuf_S,sBuf_W &
+ ,rBuf_N,rBuf_E,rBuf_S,rBuf_W
+
+integer(i_kind) itarg_n,itarg_s,itarg_w,itarg_e,imax,jmax
+logical lwest,least,lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,L,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax,ndatay
+logical l_sidesend
+integer(i_kind) g_ind,g,k
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Limit comminications to selected number of generations
+!
+
+ if(mygen_min <= my_hgen .and. my_hgen <= mygen_max) then
+ g_ind=2
+ g = my_hgen
+ l_sidesend=.true.
+ else
+ l_sidesend=.false.
+ endif
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+FILT_GRID: if(l_sidesend) then
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!
+! from mg_domain
+!
+ itarg_n = Fitarg_n(g_ind)
+ itarg_s = Fitarg_s(g_ind)
+ itarg_w = Fitarg_w(g_ind)
+ itarg_e = Fitarg_e(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+ if(least) then
+ imax = Fimax_in(g)
+ else
+ imax = im_in ! << Note that is not necesseraly im from
+ endif ! mg_parameter. Could be also imL >>>
+ if(lnorth) then
+ jmax = Fjmax_in(g)
+ else
+ jmax = jm_in
+ endif
+
+
+!----------------------------------------------------------------------
+ ndatax =km_in*(jmax+2*nby)*nbx *Lm_in
+ ndatay =km_in*imax*nby *Lm_in
+
+!
+! SEND extended halos toward WEST and EAST
+!
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km_in,1:nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+
+ do L=Lm_in,1,-1
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_W(:,i,j,L) = W(:,-nbx+i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km_in,1:nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+
+ do L=Lm_in,1,-1
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_E(:,i,j,L) = W(:,imax+i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+ end if
+
+!
+! RECEIVE extended halos from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+
+ allocate( rBuf_E(1:km_in,1:nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+
+ allocate( rBuf_W(1:km_in,1:nbx,1-nby:jmax+nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+
+ end if
+
+!
+! Assign received extended halos from WEST and EAST
+!
+
+! From west
+
+ if(lwest) then
+ do L=1,lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,i,j,L)= W(:,i,j,L)+W(:,1-i,j,L)
+ end do
+ end do
+ end do
+ else
+ do L=1,lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,i,j,L)= W(:,i,j,L)+rBuf_W(:,i,j,L)
+ end do
+ end do
+ end do
+ endif
+
+! From east
+
+ if(least) then
+ do L=1,lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax-nbx+i,j,L)= W(:,imax-nbx+i,j,L)+W(:,imax+1+nbx-i,j,L)
+ end do
+ end do
+ end do
+ else
+ do L=1,lm_in
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax-nbx+i,j,L)= W(:,imax-nbx+i,j,L)+rBuf_E(:,i,j,L)
+ end do
+ end do
+ end do
+ endif
+
+!
+! SEND halos toward SOUTH and NORTH
+!
+
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km_in,1:imax,1:nby,1:Lm_in), stat = iaerr )
+
+ do L=Lm_in,1,-1
+ do j=1-nby,0
+ do i=1,imax
+ sBuf_S(:,i,j+nby,L) = W(:,i,j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km_in,1:imax,1:nby,1:Lm_in), stat = iaerr )
+
+ do L=Lm_in,1,-1
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j,L)=W(:,i,jmax+j,L)
+ enddo
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+
+ end if
+
+!
+! RECEIVE halos from NORTH and SOUTH
+!
+!
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+
+ allocate( rBuf_N(1:km_in,1:imax,1:nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+
+ allocate( rBuf_S(1:km_in,1:imax,1:nby,1:Lm_in), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+
+ end if
+
+
+!-----------------------------------------------------------------------
+!
+! Assign received halos from SOUTH and NORTH
+!
+
+ if(lsouth) then
+ do L=1,lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j,L)= W(:,i,j,L)+W(:,i,1-j,L)
+ end do
+ end do
+ end do
+ else
+ do L=1,lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j,L)= W(:,i,j,L)+rBuf_S(:,i,j,L)
+ end do
+ end do
+ end do
+ endif
+
+! From north
+
+ if(lnorth) then
+ do L=1,lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j,L)= W(:,i,jmax-nby+j,L)+W(:,i,jmax+1+nby-j,L)
+ enddo
+ enddo
+ enddo
+ else
+ do L=1,lm_in
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j,L)= W(:,i,jmax-nby+j,L)+rBuf_N(:,i,j,L)
+ enddo
+ enddo
+ enddo
+ endif
+
+
+!
+! Set up mirror b.c. at the bottom and top of domain
+!
+ do L=1,nbz
+ W(:,:,:,1+L )=W(:,:,:, 1+L)+W(:,:,:, 1-L)
+ W(:,:,:,LM-L)=W(:,:,:,LM-L)+W(:,:,:,LM+L)
+ end do
+
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE sBufferes
+!
+
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_W, stat = ierr )
+ end if
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_E, stat = ierr )
+ end if
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_S, stat = ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_N, stat = ierr )
+ end if
+!
+! DEALLOCATE rBufferes
+!
+
+ if( itarg_w >= 0 ) then
+ deallocate( rBuf_W, stat = iderr)
+ endif
+ if( itarg_e >= 0 ) then
+ deallocate( rBuf_E, stat = iderr)
+ endif
+ if( itarg_s >= 0 ) then
+ deallocate( rBuf_S, stat = iderr)
+ endif
+ if( itarg_n >= 0 ) then
+ deallocate( rBuf_N, stat = iderr)
+ endif
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+ endif FILT_GRID
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine bocoT_3d_gh
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsend_all_g1 &
+!***********************************************************************
+! !
+! Upsend data from generation one to generation two !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,Harray,Warray,km_in)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in
+real(r_kind), dimension(km_in,1:this%imL,1:this%jmL),intent(in):: Harray
+real(r_kind), dimension(km_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: Warray
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_SW,sBuf_SE,sBuf_NW,sBuf_NE &
+ ,rBuf_SW,rBuf_SE,rBuf_NW,rBuf_NE
+
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_SW
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_SE
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_NW
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_NE
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,ndata,i,j
+integer(i_kind) isend,irecv,nebpe
+
+integer(i_kind):: mygen_dn,mygen_up
+logical:: lsendup_sw,lsendup_se,lsendup_nw,lsendup_ne,flag_up
+integer(i_kind):: itarg_up
+integer:: g_ind
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+
+!-----------------------------------------------------------------------
+ mygen_dn=1
+ mygen_up=2
+!
+! Define generational flags
+!
+ g_ind=1
+
+ lsendup_sw=Flsendup_sw(g_ind)
+ lsendup_se=Flsendup_se(g_ind)
+ lsendup_nw=Flsendup_nw(g_ind)
+ lsendup_ne=Flsendup_ne(g_ind)
+
+
+ itarg_up=Fitarg_up(g_ind)
+
+
+!-----------------------------------------------------------------------
+
+ if(my_hgen==mygen_up) then
+ Warray(:,:,:) = 0.0d0
+ endif
+
+ ndata =km_in*imL*jmL
+
+!
+! --- Send data to SW portion of processors at higher generation
+!
+
+ if( lsendup_sw ) then
+
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_SW(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_SW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SW(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SW, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+ call MPI_WAIT( sHandle(1), istat, ierr )
+
+ deallocate( sBuf_SW, stat = ierr )
+
+ endif
+
+ endif
+!
+! --- Receive SW portion of data at higher generation
+!
+
+ if( my_hgen==mygen_up .and. itargdn_sw >= 0 ) then
+
+ nebpe = itargdn_sw
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_SW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ Warray(:,i,j)=dBuf_SW(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!
+! --- Send data to SE portion of processors at higher generation
+!
+
+ if( lsendup_se ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_SE(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_SE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SE(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SE, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+ call MPI_WAIT( sHandle(2), istat, ierr )
+
+ deallocate( sBuf_SE, stat = ierr )
+
+ endif
+
+ end if
+
+!
+! --- Receive SE portion of data at higher generation
+!
+
+ if( my_hgen==mygen_up .and. itargdn_se >= 0 ) then
+
+ nebpe = itargdn_se
+
+ if(nebpe /= mype) then
+
+ call MPI_IRECV( dBuf_SE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ endif
+ do j=1,jmL
+ do i=1,imL
+ Warray(:,imL+i,j)=dBuf_SE(:,i,j)
+ enddo
+ enddo
+
+ endif
+!
+! --- Send data to NW portion of processors at higher generation
+!
+
+ if( lsendup_nw ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_NW(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_NW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NW(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NW, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(3), isend)
+
+ call MPI_WAIT( sHandle(3), istat, ierr )
+
+ deallocate( sBuf_NW, stat = ierr )
+
+ end if
+
+ end if
+
+!
+! --- Receive NW portion of data at higher generation
+!
+
+ if( my_hgen==mygen_up .and. itargdn_nw >= 0 ) then
+
+ nebpe = itargdn_nw
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_NW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ Warray(:,i,jmL+j)=dBuf_NW(:,i,j)
+ enddo
+ enddo
+
+ endif
+!
+! --- Send data to NE portion of processors at higher generation
+!
+
+ if( lsendup_ne ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_NE(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_NE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NE(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NE, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(4), isend)
+ call MPI_WAIT( sHandle(4), istat, ierr )
+
+ deallocate( sBuf_NE, stat = ierr )
+
+ endif
+
+ end if
+
+!
+! --- Receive NE portion of data at higher generation
+!
+
+ if( my_hgen==mygen_up .and. itargdn_ne >= 0 ) then
+
+ nebpe = itargdn_ne
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_NE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ Warray(:,imL+i,jmL+j)=dBuf_NE(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+!-----------------------------------------------------------------------
+endsubroutine upsend_all_g1
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsend_all_gh &
+!***********************************************************************
+! *
+! Upsend data from one grid generation to another *
+! (Just for high grid generations) *
+! !
+! - offset version - !
+! *
+!***********************************************************************
+(this,Harray,Warray,km_in,mygen_dn,mygen_up)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in
+real(r_kind), dimension(km_in,1:this%imL,1:this%jmL),intent(in):: Harray
+real(r_kind), dimension(km_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: Warray
+integer(i_kind),intent(in):: mygen_dn,mygen_up
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_SW,sBuf_SE,sBuf_NW,sBuf_NE &
+ ,rBuf_SW,rBuf_SE,rBuf_NW,rBuf_NE
+
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_SW
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_SE
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_NW
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_NE
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,ndata,i,j,L
+integer(i_kind) isend,irecv,nebpe
+
+logical:: lsendup_sw,lsendup_se,lsendup_nw,lsendup_ne,flag_up
+integer(i_kind):: itarg_up
+integer:: g_ind
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+
+!-----------------------------------------------------------------------
+!
+! Define generational flags
+!
+
+ g_ind=2
+
+ lsendup_sw=Flsendup_sw(g_ind).and.(my_hgen==mygen_dn)
+ lsendup_se=Flsendup_se(g_ind).and.(my_hgen==mygen_dn)
+ lsendup_nw=Flsendup_nw(g_ind).and.(my_hgen==mygen_dn)
+ lsendup_ne=Flsendup_ne(g_ind).and.(my_hgen==mygen_dn)
+
+ itarg_up=Fitarg_up(g_ind)
+
+
+!-----------------------------------------------------------------------
+
+ if(my_hgen==mygen_up) then
+ Warray(:,:,:)=0.0d0
+ endif
+
+ ndata =km_in*imL*jmL
+
+ if( lsendup_sw ) then
+
+ nebpe = itarg_up
+
+
+ allocate( sBuf_SW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SW(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SW, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+ call MPI_WAIT( sHandle(1), istat, ierr )
+
+ deallocate( sBuf_SW, stat = ierr )
+
+
+ end if
+
+!
+! --- Receive SW portion of data at higher generation
+!
+
+ if( my_hgen==mygen_up .and. itargdn_sw >= 0 ) then
+
+ nebpe = itargdn_sw
+
+ allocate( rBuf_SW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_SW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Warray(:,i,j)=Rbuf_SW(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!
+! --- Send data to SE portion of processors at higher generation
+!
+
+ if( lsendup_se ) then
+ nebpe = itarg_up
+
+
+ allocate( sBuf_SE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SE(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SE, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+
+ call MPI_WAIT( sHandle(2), istat, ierr )
+
+ deallocate( sBuf_SE, stat = ierr )
+
+ end if
+
+!
+! --- Receive SE portion of data at higher generation
+
+
+ if( my_hgen==mygen_up .and. itargdn_se >= 0 ) then
+ nebpe = itargdn_se
+
+
+ allocate( rBuf_SE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_SE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Warray(:,imL+i,j)=Rbuf_SE(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+!
+! --- Send data to NW portion of processors at higher generation
+!
+
+ if( lsendup_nw ) then
+ nebpe = itarg_up
+
+ allocate( sBuf_NW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NW(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NW, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+
+ call MPI_WAIT( sHandle(3), istat, ierr )
+
+ deallocate( sBuf_NW, stat = ierr )
+
+
+ end if
+
+!
+! --- Receive NW portion of data at higher generation
+!
+
+ if( my_hgen==mygen_up .and. itargdn_nw >= 0 ) then
+ nebpe = itargdn_nw
+
+
+ allocate( rBuf_NW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_NW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Warray(:,i,jmL+j)=rBuf_NW(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_NW, stat = iderr)
+
+ end if
+
+!
+! --- Send data to NE portion of processors at higher generation
+!
+
+ if( lsendup_ne ) then
+ nebpe = itarg_up
+
+ allocate( sBuf_NE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NE(:,i,j) = Harray(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NE, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+
+ call MPI_WAIT( sHandle(4), istat, ierr )
+
+ deallocate( sBuf_NE, stat = ierr )
+
+ end if
+
+!
+! --- Receive NE portion of data at higher generation
+!
+
+ if( my_hgen==mygen_up .and. itargdn_ne >= 0 ) then
+ nebpe = itargdn_ne
+
+ allocate( rBuf_NE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_NE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Warray(:,imL+i,jmL+j)=rBuf_NE(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_NE, stat = iderr)
+
+ endif
+
+!-----------------------------------------------------------------------
+endsubroutine upsend_all_gh
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsend_all_gh &
+!***********************************************************************
+! *
+! Downsending data from low resolution pes (mygen_up) *
+! to the concurent high-resolution pes (mygen_dn) *
+! and add the existing and the recevied values *
+! !
+! - offset version - !
+! *
+!***********************************************************************
+(this,Warray,Harray,km_in,mygen_up,mygen_dn)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in
+real(r_kind), dimension(km_in,1:this%im,1:this%jm),intent(in):: Warray
+real(r_kind), dimension(km_in,1:this%imL,1:this%jmL),intent(out):: Harray
+integer, intent(in):: mygen_up,mygen_dn
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_SW,sBuf_SE,sBuf_NW,sBuf_NE &
+ ,rBuf_SW,rBuf_SE,rBuf_NW,rBuf_NE
+
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_SW
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_SE
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_NW
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_NE
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,ndata,i,j,L
+integer(i_kind) isend,irecv,nebpe
+
+logical:: lsendup_sw,lsendup_se,lsendup_nw,lsendup_ne
+integer(i_kind):: itarg_up
+integer(i_kind):: g_ind
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+
+ Harray(:,:,:) = 0.0d0
+!
+! Define generational flags
+!
+
+ g_ind=2
+ lsendup_sw=Flsendup_sw(g_ind).and.(my_hgen==mygen_dn)
+ lsendup_se=Flsendup_se(g_ind).and.(my_hgen==mygen_dn)
+ lsendup_nw=Flsendup_nw(g_ind).and.(my_hgen==mygen_dn)
+ lsendup_ne=Flsendup_ne(g_ind).and.(my_hgen==mygen_dn)
+
+ itarg_up=Fitarg_up(g_ind)
+
+ ndata =km_in*imL*jmL
+
+!
+! --- Send data from SW portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+
+ if(my_hgen==mygen_up .and. itargdn_sw >= 0 ) then
+ nebpe = itargdn_sw
+
+
+ allocate( sBuf_SW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SW(:,i,j) = Warray(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SW, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_SW, stat = ierr )
+
+
+ endif
+!
+! --- Receive SW portion of data at lower generation
+
+
+ if( lsendup_sw ) then
+
+ nebpe = itarg_up
+
+
+ allocate( rBuf_SW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_SW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Harray(:,i,j)=rBuf_SW(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_SW, stat = iderr)
+
+ endif
+
+!
+! --- Send data from SE portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ if(my_hgen==mygen_up .and. itargdn_se >= 0 ) then
+ nebpe = itargdn_se
+
+ allocate( sBuf_SE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SE(:,i,j) = Warray(:,imL+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SE, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_SE, stat = ierr )
+
+
+ endif
+!
+! --- Receive SE portion of data at lower generation
+
+
+ if( lsendup_se ) then
+ nebpe = itarg_up
+
+
+ allocate( rBuf_SE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_SE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Harray(:,i,j)=Rbuf_SE(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_SE, stat = iderr)
+
+ end if
+
+!
+! --- Send data from NW portion of processors at the higher generation
+! to corresponding PE's at lower generantion
+
+ if(my_hgen==mygen_up .and. itargdn_nw >= 0 ) then
+ nebpe = itargdn_nw
+
+
+ allocate( sBuf_NW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NW(:,i,j) = Warray(:,i,jmL+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NW, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_NW, stat = ierr )
+
+
+ endif
+!
+! --- Receive NW portion of data at lower generation
+
+
+ if( lsendup_nw ) then
+
+ nebpe = itarg_up
+
+ allocate( rBuf_NW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_NW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Harray(:,i,j)=Rbuf_NW(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_NW, stat = iderr)
+
+
+ end if
+
+
+! --- Send data from NE portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ if(my_hgen==mygen_up .and. itargdn_ne >= 0 ) then
+ nebpe = itargdn_ne
+
+
+ allocate( sBuf_NE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NE(:,i,j) = Warray(:,imL+i,jmL+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NE, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_NE, stat = ierr )
+
+
+ endif
+!
+! --- Receive NE portion of data at lower generation
+!
+
+ if( lsendup_ne ) then
+ nebpe = itarg_up
+
+ allocate( rBuf_NE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_NE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Harray(:,i,j)=rBuf_NE(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_NE, stat = iderr)
+
+ end if
+
+!-----------------------------------------------------------------------
+endsubroutine downsend_all_gh
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsend_all_g2 &
+!***********************************************************************
+! *
+! Downsending data from low resolution pes (mygen_up) *
+! to the concurent high-resolution pes (mygen_dn) *
+! and add the existing and the recevied values *
+! *
+! - offset version - *
+! *
+!***********************************************************************
+(this,Warray,Harray,km_in)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in
+real(r_kind), dimension(km_in,1:this%im,1:this%jm),intent(in):: Warray
+real(r_kind), dimension(km_in,1:this%imL,1:this%jmL),intent(out):: Harray
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_SW,sBuf_SE,sBuf_NW,sBuf_NE
+
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_SW
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_SE
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_NW
+real(r_kind),dimension(1:km_in,1:this%imL,1:this%jmL):: dBuf_NE
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,ndata,i,j,L
+integer(i_kind) isend,irecv,nebpe
+
+logical:: lsendup_sw,lsendup_se,lsendup_nw,lsendup_ne
+integer:: mygen_up,mygen_dn
+integer(i_kind):: itarg_up
+integer(i_kind):: g_ind
+!-----------------------------------------------------------------------
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!
+! Define generational flags
+!
+ mygen_up=2
+ mygen_dn=1
+
+ g_ind=1
+ lsendup_sw=Flsendup_sw(g_ind)
+ lsendup_se=Flsendup_se(g_ind)
+ lsendup_nw=Flsendup_nw(g_ind)
+ lsendup_ne=Flsendup_ne(g_ind)
+
+ itarg_up=Fitarg_up(g_ind)
+
+
+ ndata =km_in*imL*jmL
+
+
+!
+! Send data down to generation 1
+!
+LSEND: if(my_hgen==mygen_up) then
+!
+! --- Send data from SW portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ nebpe = itargdn_sw
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_SW(:,i,j) = Warray(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_SW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SW(:,i,j) = Warray(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SW, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_SW, stat = ierr )
+
+ endif
+!
+! --- Send data from SE portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ nebpe = itargdn_se
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_SE(:,i,j) = Warray(:,imL+i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_SE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SE(:,i,j) = Warray(:,imL+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SE, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_SE, stat = ierr )
+
+ endif
+
+! --- Send data from NW portion of processors at the higher generation
+! to corresponding PE's at lower generantion
+
+ nebpe = itargdn_nw
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_NW(:,i,j) = Warray(:,i,jmL+j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_NW(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NW(:,i,j) = Warray(:,i,jmL+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NW, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(3), isend)
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_NW, stat = ierr )
+
+ endif
+
+!
+! --- Send data from NE portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ nebpe = itargdn_ne
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_NE(:,i,j) = Warray(:,imL+i,jmL+j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_NE(1:km_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NE(:,i,j) = Warray(:,imL+i,jmL+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NE, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(4), isend)
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_NE, stat = ierr )
+
+ endif
+
+
+ endif LSEND
+
+!
+! --- Receive SW portion of data at lower generation
+!
+
+ if( lsendup_sw .and. mype /= itarg_up ) then
+
+ nebpe = itarg_up
+
+
+ call MPI_IRECV( dBuf_SW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+
+ else &
+
+!
+! --- Receive SE portion of data at lower generation
+
+
+ if( lsendup_se .and. mype /= itarg_up) then
+
+ nebpe = itarg_up
+
+ call MPI_IRECV( dBuf_SE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+
+ else &
+
+
+!
+! --- Receive NW portion of data at lower generation
+
+
+ if( lsendup_nw .and. mype /= itarg_up) then
+
+ nebpe = itarg_up
+
+ call MPI_IRECV( dBuf_NW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+
+ else &
+
+
+!
+! --- Receive NE portion of data at lower generation
+!
+
+ if( lsendup_ne .and. mype /= itarg_up) then
+ nebpe = itarg_up
+
+ call MPI_IRECV( dBuf_NE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+
+ end if
+
+!
+! Assign received and prescribed values
+!
+ if( lsendup_sw ) then
+
+ do j=1,jmL
+ do i=1,imL
+ Harray(:,i,j)=dBuf_SW(:,i,j)
+ enddo
+ enddo
+
+ else &
+ if( lsendup_se ) then
+
+ do j=1,jmL
+ do i=1,imL
+ Harray(:,i,j)=dBuf_SE(:,i,j)
+ enddo
+ enddo
+
+ else &
+ if( lsendup_nw ) then
+
+ do j=1,jmL
+ do i=1,imL
+ Harray(:,i,j)=dBuf_NW(:,i,j)
+ enddo
+ enddo
+
+ else &
+ if( lsendup_ne ) then
+
+ do j=1,jmL
+ do i=1,imL
+ Harray(:,i,j)=dBuf_NE(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+!-----------------------------------------------------------------------
+endsubroutine downsend_all_g2
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocox_2d_g1 &
+!**********************************************************************!
+! !
+! Side sending subroutine: !
+! Supplies nbx lines of halos in x direction assuming mirror boundary !
+! conditions at the end of domain. Version for generation 1 !
+! !
+! - offset version - !
+! !
+!**********************************************************************!
+(this,W,km_in,im_in,jm_in,nbx,nby)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby
+real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: sBuf_E,sBuf_W &
+ ,rBuf_E,rBuf_W
+
+integer(i_kind) itarg_w,itarg_e,imax,jmax
+logical:: lwest,least
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,l,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax
+integer(i_kind) g_ind,g
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Limit communications to selected number of generations
+!
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+!
+! from mg_domain
+!
+ g_ind = 1
+
+ itarg_w = Fitarg_w(g_ind)
+ itarg_e = Fitarg_e(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+
+ imax = im_in
+ jmax = jm_in
+
+
+!-----------------------------------------------------------------------
+ ndatax = km_in*jmax*nbx
+
+!----------------------------------------------------------------------
+!
+! SEND extended boundaries toward WEST and EAST
+!
+
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km_in,nbx,1:jmax), stat = iaerr )
+
+ do j=1,jmax
+ do i=1,nbx
+ sBuf_W(:,i,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km_in,nbx,1:jmax), stat = iaerr )
+
+ do j=1,jmax
+ do i=1,nbx
+ sBuf_E(:,i,j) = W(:,imax-nbx+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE boundaries from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( rBuf_E(1:km_in,nbx,1:jmax), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+ allocate( rBuf_W(1:km_in,nbx,1:jmax), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ end if
+
+
+!
+! Assign received values from EAST and WEST
+!
+
+! From west
+
+ if(lwest) then
+
+ do j=1,jmax
+ do i=1,nbx
+ W(:,-nbx+i,j)= W(:,nbx+1-i,j)
+ end do
+ end do
+
+ else
+
+ do j=1,jmax
+ do i=1,nbx
+ W(:,-nbx+i,j)= rBuf_W(:,i,j)
+ enddo
+ enddo
+
+
+ endif
+
+! From east
+
+ if(least) then
+
+ do j=1,jmax
+ do i=1,nbx
+ W(:,imax+i,j)=W(:,imax+1-i,j)
+ end do
+ end do
+
+ else
+
+ do j=1,jmax
+ do i=1,nbx
+ W(:,imax+i,j)=rBuf_E(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+
+ if( itarg_e >= 0 ) then
+ deallocate( rBuf_E, stat = iderr)
+ endif
+ if( itarg_w >= 0 ) then
+ deallocate( rBuf_W, stat = iderr)
+ endif
+
+!
+! DEALLOCATE sBufferes
+!
+
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_E, stat = ierr )
+ end if
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_W, stat = ierr )
+ end if
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine bocox_2d_g1
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocox_2d_gh &
+!**********************************************************************!
+! !
+! Side sending subroutine: !
+! Supplies nbx lines of halos in x direction assuming mirror boundary !
+! conditions at the end of domain. Version for high generations !
+! !
+! - offset version - !
+! !
+!**********************************************************************!
+(this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: sBuf_E,sBuf_W &
+ ,rBuf_E,rBuf_W
+
+integer(i_kind) itarg_w,itarg_e,imax,jmax
+logical:: lwest,least,lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,l,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax
+integer(i_kind) g_ind,g
+logical l_sidesend
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Limit communications to selected number of generations
+!
+
+ if(mygen_min <= my_hgen .and. my_hgen <= mygen_max) then
+ g_ind=2
+ g = my_hgen
+ l_sidesend=.true.
+ else
+ l_sidesend=.false.
+ endif
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+FILT_GRID: if(l_sidesend) then
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+!
+! from mg_domain
+!
+ itarg_w = Fitarg_w(g_ind)
+ itarg_e = Fitarg_e(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+
+ if(least) then
+ imax = Fimax_in(g)
+ else
+ imax = im ! << Note that is not necesseraly im from
+ endif ! mg_parameter. Could be also imL >>>
+ if(lnorth) then
+ jmax = Fjmax_in(g)
+ else
+ jmax = jm
+ endif
+
+
+!-----------------------------------------------------------------------
+ ndatax = km_in*jmax*nbx
+
+!
+! SEND halos to WEST and EASTH
+!
+
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km_in,nbx,1:jmax), stat = iaerr )
+
+ do j=1,jmax
+ do i=1,nbx
+ sBuf_W(:,i,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km_in,nbx,1:jmax), stat = iaerr )
+
+ do j=1,jmax
+ do i=1,nbx
+ sBuf_E(:,i,j) = W(:,imax-nbx+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE extended boundaries from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( rBuf_E(1:km_in,nbx,1:jmax), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+ allocate( rBuf_W(1:km_in,nbx,1:jmax), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ end if
+
+!
+! Assign received values from WEST and EAST
+!
+
+! From west
+
+ if(lwest) then
+
+ do j=1,jmax
+ do i=1,nbx
+ W(:,-nbx+i,j)= W(:,nbx+1-i,j)
+ end do
+ end do
+
+ else
+
+ do j=1,jmax
+ do i=1,nbx
+ W(:,-nbx+i,j)= rBuf_W(:,i,j)
+ enddo
+ enddo
+
+
+ endif
+
+! From east
+
+ if(least) then
+
+ do j=1,jmax
+ do i=1,nbx
+ W(:,imax+i,j)=W(:,imax-i,j)
+ end do
+ end do
+
+ else
+
+ do j=1,jmax
+ do i=1,nbx
+ W(:,imax+i,j)=rBuf_E(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+
+ if( itarg_e >= 0 ) then
+ deallocate( rBuf_E, stat = iderr)
+ endif
+ if( itarg_w >= 0 ) then
+ deallocate( rBuf_W, stat = iderr)
+ endif
+
+!
+! DEALLOCATE sBufferes
+!
+
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_E, stat = ierr )
+ end if
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_W, stat = ierr )
+ end if
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+ endif FILT_GRID
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine bocox_2d_gh
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocoy_2d_g1 &
+!**********************************************************************!
+! !
+! Side sending subroutine: !
+! Supplies nby lines of halos in y direction assuming mirror boundary !
+! conditions at the end of domain. Version for generation 1 !
+! !
+! - offset version - !
+! !
+!**********************************************************************!
+(this,W,km_in,im_in,jm_in,nbx,nby)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby
+real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: sBuf_N,sBuf_S &
+ ,rBuf_N,rBuf_S
+
+integer(i_kind) itarg_n,itarg_s,imax,jmax
+logical:: lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,l,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatay
+integer(i_kind) g_ind,g
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Limit communications to selected number of generations
+!
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+!
+! from mg_domain
+!
+ g_ind = 1
+
+ itarg_n = Fitarg_n(g_ind)
+ itarg_s = Fitarg_s(g_ind)
+
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+ imax = im_in
+ jmax = jm_in
+
+
+!-----------------------------------------------------------------------
+ ndatay = km_in*imax*nby
+
+
+!
+! SEND boundaries toward SOUTH and NORTH
+!
+
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km_in,1:imax,nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_S(:,i,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km_in,1:imax,nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j)=W(:,i,jmax-nby+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+
+ end if
+
+!
+! RECEIVE boundaries from NORTH and SOUTH
+!
+
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( rBuf_N(1:km_in,1:imax,nby), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( rBuf_S(1:km_in,1:imax,nby), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ end if
+!
+! Assign received values from NORTH and SOUTH
+!
+
+! --- from NORTH ---
+
+ if( lnorth) then
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j)=W(:,i,jmax+1-j)
+ enddo
+ enddo
+
+ else
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j)=rBuf_N(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+! From SOUTH
+
+ if(lsouth) then
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j)=W(:,i,nby+1-j)
+ end do
+ end do
+
+ else
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j)=rBuf_S(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+
+ if( itarg_s >= 0 ) then
+ deallocate( rBuf_S, stat = iderr)
+ endif
+ if( itarg_n >= 0 ) then
+ deallocate( rBuf_N, stat = iderr)
+ endif
+
+!
+! DEALLOCATE sBufferes
+!
+
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_S, stat = ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_N, stat = ierr )
+ end if
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine bocoy_2d_g1
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocoy_2d_gh &
+!**********************************************************************!
+! !
+! Side sending subroutine: !
+! Supplies nby lines of halos in y direction assuming mirror boundary !
+! conditions at the end of domain. Version for high generations !
+! !
+! - offset version - !
+! !
+!**********************************************************************!
+(this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: sBuf_N,sBuf_S &
+ ,rBuf_N,rBuf_S
+
+integer(i_kind) itarg_n,itarg_s,imax,jmax
+logical:: lwest,least,lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,l,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatay
+integer(i_kind) g_ind,g
+logical l_sidesend
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Limit communications to selected number of generations
+!
+
+ if(mygen_min <= my_hgen .and. my_hgen <= mygen_max) then
+ g_ind=2
+ g = my_hgen
+ l_sidesend=.true.
+ else
+ l_sidesend=.false.
+ endif
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+FILT_GRID: if(l_sidesend) then
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+!
+! from mg_domain
+!
+ itarg_n = Fitarg_n(g_ind)
+ itarg_s = Fitarg_s(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+
+ if(least) then
+ imax = Fimax_in(g)
+ else
+ imax = im_in ! << Note that is not necesseraly im from
+ endif ! mg_parameter. Could be also imL >>>
+ if(lnorth) then
+ jmax = Fjmax_in(g)
+ else
+ jmax = jm_in
+ endif
+
+
+!-----------------------------------------------------------------------
+ ndatay = km_in*imax*nby
+
+!
+! SEND boundaries to SOUTH and NORTH
+!
+
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km_in,1:imax,nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_S(:,i,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km_in,1:imax,nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j)=W(:,i,jmax-nby+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+
+ end if
+!
+! RECEIVE boundaries from NORTH and SOUTH
+!
+
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( rBuf_N(1:km_in,1:imax,nby), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( rBuf_S(1:km_in,1:imax,nby), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ end if
+
+!
+! Assign received values from NORTH and SOUTH
+!
+
+! --- from NORTH ---
+
+ if( lnorth) then
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j)=W(:,i,jmax+1-j)
+ enddo
+ enddo
+
+ else
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j)=rBuf_N(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+! From south
+
+ if(lsouth) then
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j)=W(:,i,nby+1-j)
+ end do
+ end do
+
+ else
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j)=rBuf_S(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+
+ if( itarg_s >= 0 ) then
+ deallocate( rBuf_S, stat = iderr)
+ endif
+ if( itarg_n >= 0 ) then
+ deallocate( rBuf_N, stat = iderr)
+ endif
+
+!
+! DEALLOCATE sBufferes
+!
+
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_S, stat = ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_N, stat = ierr )
+ end if
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+ endif FILT_GRID
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine bocoy_2d_gh
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocoTx_2d_g1 &
+!***********************************************************************
+! !
+! Side sending subroutine: !
+! Supplies nbx lines close to edges of the subdomins from neighboring !
+! halos in x direction assuming mirror boundary conditions !
+! Version for generation 1 !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,km_in,im_in,jm_in,nbx,nby)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby
+real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: sBuf_E,sBuf_W &
+ ,rBuf_E,rBuf_W
+
+integer(i_kind) itarg_w,itarg_e,imax,jmax
+logical lwest,least
+
+integer(i_kind) sHandle(2),rHandle(2),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,L,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax
+logical l_sidesend
+integer(i_kind) g_ind,g,k
+!-----------------------------------------------------------------------
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!
+! Limit comminications to selected number of generations
+!
+
+
+ g_ind=1
+!
+! from mg_domain
+!
+ itarg_w = Fitarg_w(g_ind)
+ itarg_e = Fitarg_e(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+
+ imax = im_in
+ jmax = jm_in
+
+
+!----------------------------------------------------------------------
+ ndatax =km_in*jmax*nbx
+
+!
+! SEND halos toward WEST and EAST
+!
+
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km_in,1:nbx,1:jmax), stat = iaerr )
+
+ do j=1,jmax
+ do i=1-nbx,0
+ sBuf_W(:,i+nbx,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km_in,1:nbx,1:jmax), stat = iaerr )
+
+ do j=1,jmax
+ do i=1,nbx
+ sBuf_E(:,i,j) = W(:,imax+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE halos from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+
+ allocate( rBuf_E(1:km_in,1:nbx,1:jmax), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+
+ allocate( rBuf_W(1:km_in,1:nbx,1:jmax), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+
+ end if
+
+!
+! Assign received halos from WEST and EAST to interrior of domains
+!
+
+! From west
+
+ if(lwest) then
+ do j=1,jmax
+ do i=1,nbx
+ W(:,i,j)= W(:,i,j)+W(:,1-i,j)
+ end do
+ end do
+ else
+ do j=1,jmax
+ do i=1,nbx
+ W(:,i,j)= W(:,i,j)+rBuf_W(:,i,j)
+ end do
+ end do
+ endif
+
+! From east
+
+ if(least) then
+ do j=1,jmax
+ do i=1,nbx
+ W(:,imax-nbx+i,j)= W(:,imax-nbx+i,j)+W(:,imax+nbx+1-i,j)
+ end do
+ end do
+ else
+ do j=1,jmax
+ do i=1,nbx
+ W(:,imax-nbx+i,j)= W(:,imax-nbx+i,j)+rBuf_E(:,i,j)
+ end do
+ end do
+ endif
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+
+ if( itarg_w >= 0 ) then
+ deallocate( rBuf_W, stat = iderr)
+ endif
+ if( itarg_e >= 0 ) then
+ deallocate( rBuf_E, stat = iderr)
+ endif
+
+!
+! DEALLOCATE sBufferes
+!
+
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ end if
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ end if
+
+!-----------------------------------------------------------------------
+endsubroutine bocoTx_2d_g1
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocoTx_2d_gh &
+!***********************************************************************
+! !
+! Side sending subroutine: !
+! Supplies nbx lines close to edges of the subdomins from neighboring !
+! halos in x direction assuming mirror boundary conditions !
+! Version for high generations !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: sBuf_E,sBuf_W &
+ ,rBuf_E,rBuf_W
+integer(i_kind) itarg_w,itarg_e,imax,jmax
+logical lwest,least,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,L,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax,ndatay
+logical l_sidesend
+integer(i_kind) g_ind,g,k
+!-----------------------------------------------------------------------
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!
+! Limit comminications to selected number of generations
+!
+
+ if(mygen_min <= my_hgen .and. my_hgen <= mygen_max) then
+ g_ind=2
+ g = my_hgen
+ l_sidesend=.true.
+ else
+ l_sidesend=.false.
+ endif
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+FILT_GRID: if(l_sidesend) then
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!
+! from mg_domain
+!
+ itarg_w = Fitarg_w(g_ind)
+ itarg_e = Fitarg_e(g_ind)
+
+ lwest = Flwest(g_ind)
+ least = Fleast(g_ind)
+
+ lnorth = Flnorth(g_ind)
+
+
+ if(least) then
+ imax = Fimax_in(g)
+ else
+ imax = im_in ! << Note that is not necesseraly im from
+ endif ! mg_parameter. Could be also imL >>>
+ if(lnorth) then
+ jmax = Fjmax_in(g)
+ else
+ jmax = jm_in
+ endif
+
+
+!----------------------------------------------------------------------
+ ndatax =km_in*jmax*nbx
+!
+! SEND halos toward WEST and EAST
+!
+
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km_in,1:nbx,1:jmax), stat = iaerr )
+
+ do j=1,jmax
+ do i=1-nbx,0
+ sBuf_W(:,i+nbx,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km_in,1:nbx,1:jmax), stat = iaerr )
+
+ do j=1,jmax
+ do i=1,nbx
+ sBuf_E(:,i,j) = W(:,imax+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE halos from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( rBuf_E(1:km_in,1:nbx,1:jmax), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+ allocate( rBuf_W(1:km_in,1:nbx,1:jmax), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ end if
+!
+! Assign received values from WEST and EAST
+!
+
+! From west
+
+ if(lwest) then
+ do j=1,jmax
+ do i=1,nbx
+ W(:,i,j)= W(:,i,j)+W(:,1-i,j)
+ end do
+ end do
+ else
+ do j=1,jmax
+ do i=1,nbx
+ W(:,i,j)= W(:,i,j)+rBuf_W(:,i,j)
+ end do
+ end do
+ endif
+
+! From east
+
+ if(least) then
+ do j=1,jmax
+ do i=1,nbx
+ W(:,imax-nbx+i,j)= W(:,imax-nbx+i,j)+W(:,imax+nbx+1-i,j)
+ end do
+ end do
+ else
+ do j=1,jmax
+ do i=1,nbx
+ W(:,imax-nbx+i,j)= W(:,imax-nbx+i,j)+rBuf_E(:,i,j)
+ end do
+ end do
+ endif
+
+!-----------------------------------------------------------------------
+
+! DEALLOCATE rBufferes
+
+ if( itarg_w >= 0 ) then
+ deallocate( rBuf_W, stat = iderr)
+ end if
+ if( itarg_e >= 0 ) then
+ deallocate( rBuf_E, stat = iderr)
+ end if
+
+! DEALLOCATE sBufferes
+
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ end if
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ end if
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+ endif FILT_GRID
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine bocoTx_2d_gh
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocoTy_2d_g1 &
+!***********************************************************************
+! !
+! Side sending subroutine: !
+! Supplies nby lines close to edges of the subdomins from neighboring !
+! halos in y direction assuming mirror boundary conditions !
+! Version for generation 1 !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,km_in,im_in,jm_in,nbx,nby)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby
+real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: sBuf_N,sBuf_S &
+ ,rBuf_N,rBuf_S
+
+integer(i_kind) itarg_n,itarg_s,imax,jmax
+logical lsouth,lnorth
+
+integer(i_kind) sHandle(2),rHandle(2),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,L,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatay
+logical l_sidesend
+integer(i_kind) g_ind,g,k
+!-----------------------------------------------------------------------
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!
+! Limit comminications to selected number of generations
+!
+
+ g_ind=1
+!
+! from mg_domain
+!
+ itarg_n = Fitarg_n(g_ind)
+ itarg_s = Fitarg_s(g_ind)
+
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+ imax = im_in
+ jmax = jm_in
+
+
+!----------------------------------------------------------------------
+ ndatay =km_in*imax*nby
+
+!
+! SEND SOUTH and NORTH halos
+!
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km_in,1:imax,1:nby), stat = iaerr )
+
+ do j=1-nby,0
+ do i=1,imax
+ sBuf_S(:,i,j+nby) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km_in,1:imax,1:nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j)=W(:,i,jmax+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE halos from NORTH and SOUTH
+!
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+
+ allocate( rBuf_N(1:km_in,1:imax,1:nby), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+
+ allocate( rBuf_S(1:km_in,1:imax,1:nby), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+
+ end if
+
+!
+! ASSIGN received values from SOUTH and NORTH
+!
+
+! From south
+
+ if(lsouth) then
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j)= W(:,i,j)+W(:,i,1-j)
+ end do
+ end do
+ else
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j)= W(:,i,j)+rBuf_S(:,i,j)
+ end do
+ end do
+ endif
+
+! From north
+
+ if(lnorth) then
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j)= W(:,i,jmax-nby+j)+W(:,i,jmax+nby+1-j)
+ enddo
+ enddo
+ else
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j)= W(:,i,jmax-nby+j)+rBuf_N(:,i,j)
+ enddo
+ enddo
+ endif
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+
+ if( itarg_s >= 0 ) then
+ deallocate( rBuf_S, stat = iderr)
+ end if
+ if( itarg_n >= 0 ) then
+ deallocate( rBuf_N, stat = iderr)
+ end if
+
+!
+! DEALLOCATE sBufferes
+!
+
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ end if
+
+
+!-----------------------------------------------------------------------
+endsubroutine bocoTy_2d_g1
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocoTy_2d_gh &
+!***********************************************************************
+! !
+! Side sending subroutine: !
+! Supplies nby lines close to edges of the subdomins from neighboring !
+! halos in y direction assuming mirror boundary conditions !
+! Version for high generations !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: sBuf_N,sBuf_S &
+ ,rBuf_N,rBuf_S
+integer(i_kind) itarg_n,itarg_s,itarg_e,imax,jmax
+logical least,lsouth,lnorth
+
+integer(i_kind) sHandle(2),rHandle(2),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,L,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatay
+logical l_sidesend
+integer(i_kind) g_ind,g,k
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Limit comminications to selected number of generations
+!
+
+
+ if(mygen_min <= my_hgen .and. my_hgen <= mygen_max) then
+ g_ind=2
+ g = my_hgen
+ l_sidesend=.true.
+ else
+ l_sidesend=.false.
+ endif
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+FILT_GRID: if(l_sidesend) then
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!
+! from mg_domain
+!
+ itarg_n = Fitarg_n(g_ind)
+ itarg_s = Fitarg_s(g_ind)
+
+ least = Fleast(g_ind)
+ lsouth = Flsouth(g_ind)
+ lnorth = Flnorth(g_ind)
+
+
+ if(least) then
+ imax = Fimax_in(g)
+ else
+ imax = im_in ! << Note that is not necesseraly im from
+ endif ! mg_parameter. Could be also imL >>>
+ if(lnorth) then
+ jmax = Fjmax_in(g)
+ else
+ jmax = jm_in
+ endif
+
+
+!----------------------------------------------------------------------
+
+ ndatay =km_in*imax*nby
+!
+! SEND halos toward SOUTH and NORTH
+!
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km_in,1:imax,1:nby), stat = iaerr )
+
+ do j=1-nby,0
+ do i=1,imax
+ sBuf_S(:,i,j+nby) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km_in,1:imax,1:nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j)=W(:,i,jmax+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE halos from NORTH and SOUTH
+!
+!
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+
+ allocate( rBuf_N(1:km_in,1:imax,1:nby), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+
+ allocate( rBuf_S(1:km_in,1:imax,1:nby), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+
+ end if
+
+!
+! Assign received values from SOUTH and NORTH
+!
+
+! From south
+
+ if(lsouth) then
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j)= W(:,i,j)+W(:,i,1-j)
+ end do
+ end do
+ else
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j)= W(:,i,j)+rBuf_S(:,i,j)
+ end do
+ end do
+ endif
+
+! From north
+
+ if(lnorth) then
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j)= W(:,i,jmax-nby+j)+W(:,i,jmax+nby+1-j)
+ enddo
+ enddo
+ else
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j)= W(:,i,jmax-nby+j)+rBuf_N(:,i,j)
+ enddo
+ enddo
+ endif
+
+!-----------------------------------------------------------------------
+
+! DEALLOCATE rBufferes
+
+ if( itarg_s >= 0 ) then
+ deallocate( rBuf_S, stat = iderr)
+ end if
+ if( itarg_n >= 0 ) then
+ deallocate( rBuf_N, stat = iderr)
+ end if
+
+! DEALLOCATE sBufferes
+
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ end if
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+ endif FILT_GRID
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine bocoTy_2d_gh
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine boco_2d_loc &
+!**********************************************************************!
+! !
+! Side sending subroutine: !
+! Supplies (nbx,nby) lines of halos in (x,y) directions assuming !
+! mirror boundary conditions. Version for localiztion !
+! !
+! - offset version - !
+! !
+!**********************************************************************!
+(this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,g)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,g
+real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_N,sBuf_E,sBuf_S,sBuf_W &
+ ,rBuf_N,rBuf_E,rBuf_S,rBuf_W
+
+integer(i_kind) itarg_n,itarg_s,itarg_w,itarg_e,imax,jmax
+logical:: lwest,least,lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,l,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax,ndatay
+integer(i_kind) g_ind
+logical l_sidesend
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Limit communications to selected number of generations
+!
+
+ l_sidesend=.true.
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+FILT_GRID: if(l_sidesend) then
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+!
+! from mg_domain
+!
+ itarg_n = Fitarg_n_loc(g)
+ itarg_s = Fitarg_s_loc(g)
+ itarg_w = Fitarg_w_loc(g)
+ itarg_e = Fitarg_e_loc(g)
+
+ lwest = Flwest_loc(g)
+ least = Fleast_loc(g)
+ lsouth = Flsouth_loc(g)
+ lnorth = Flnorth_loc(g)
+
+
+!
+! Keep this for now but use only Mod(nxm,8)=Mod(nym,8)=0
+!
+
+ if(least) then
+ imax = Fimax_in(g)
+ else
+ imax = im_in ! << Note that is not necesseraly im from
+ endif ! mg_parameter. Could be also imL >>>
+ if(lnorth) then
+ jmax = Fjmax_in(g)
+ else
+ jmax = jm_in
+ endif
+
+
+!-----------------------------------------------------------------------
+ ndatay = km_in*imax*nby
+ ndatax = km_in*(jmax+2*nby)*nbx
+
+
+!
+! SEND boundaries to SOUTH and NORTH
+!
+
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km_in,1:imax,nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_S(:,i,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km_in,1:imax,nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j)=W(:,i,jmax-nby+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+
+ end if
+!
+! RECEIVE boundaries from NORTH and SOUTH
+!
+
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( rBuf_N(1:km_in,1:imax,nby), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( rBuf_S(1:km_in,1:imax,nby), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ end if
+
+!
+! Assign received values from NORTH and SOUTH
+!
+
+
+! From south
+
+ if(lsouth) then
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j)=W(:,i,nby+1-j)
+ end do
+ end do
+
+ else
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,-nby+j)=rBuf_S(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+! --- from NORTH ---
+
+ if( lnorth) then
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j)=W(:,i,jmax+1-j)
+ enddo
+ enddo
+
+ else
+
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax+j)=rBuf_N(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!
+! SEND extended boundaries to WEST and EASTH
+!
+
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_W(:,i,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_E(:,i,j) = W(:,imax-nbx+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE extended boundaries from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( rBuf_E(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+ allocate( rBuf_W(1:km_in,nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ end if
+
+!
+! Assign received values from WEST and EAST
+!
+
+! From west
+
+ if(lwest) then
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,-nbx+i,j)= W(:,nbx+1-i,j)
+ end do
+ end do
+
+ else
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,-nbx+i,j)= rBuf_W(:,i,j)
+ enddo
+ enddo
+
+
+ endif
+
+! From east
+
+ if(least) then
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax+i,j)=W(:,imax+1-i,j)
+ end do
+ end do
+
+ else
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax+i,j)=rBuf_E(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!-----------------------------------------------------------------------
+!
+! DEALLOCATE rBufferes
+!
+ if( itarg_w >= 0 ) then
+ deallocate( rBuf_W, stat = iderr)
+ end if
+ if( itarg_e >= 0 ) then
+ deallocate( rBuf_E, stat = iderr)
+ end if
+ if( itarg_s >= 0 ) then
+ deallocate( rBuf_S, stat = iderr)
+ end if
+ if( itarg_n >= 0 ) then
+ deallocate( rBuf_N, stat = iderr)
+ end if
+
+!
+! DEALLOCATE sBufferes
+!
+
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_W, stat = ierr )
+ end if
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_E, stat = ierr )
+ end if
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_S, stat = ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_N, stat = ierr )
+ end if
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+ endif FILT_GRID
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine boco_2d_loc
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine bocoT_2d_loc &
+!***********************************************************************
+! !
+! Supply n-lines inside of domains, including edges, with halos from !
+! the surrounding domains. Assume mirror boundary conditions at the !
+! boundaries of the domain. Vesrion for localization. !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,g)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,g
+real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_N,sBuf_E,sBuf_S,sBuf_W &
+ ,rBuf_N,rBuf_E,rBuf_S,rBuf_W
+integer(i_kind) itarg_n,itarg_s,itarg_w,itarg_e,imax,jmax
+logical lwest,least,lsouth,lnorth
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,L,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind) ndatax,ndatay
+logical l_sidesend
+integer(i_kind) g_ind,k
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Limit comminications to selected number of generations
+!
+
+
+ g_ind=g
+ l_sidesend=.true.
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+FILT_GRID: if(l_sidesend) then
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!
+! from mg_domain
+!
+ itarg_n = Fitarg_n_loc(g_ind)
+ itarg_s = Fitarg_s_loc(g_ind)
+ itarg_w = Fitarg_w_loc(g_ind)
+ itarg_e = Fitarg_e_loc(g_ind)
+
+ lwest = Flwest_loc(g_ind)
+ least = Fleast_loc(g_ind)
+ lsouth = Flsouth_loc(g_ind)
+ lnorth = Flnorth_loc(g_ind)
+
+
+ if(least) then
+ imax = Fimax_in(g)
+ else
+ imax = im_in ! << Note that is not necesseraly im from
+ endif ! mg_parameter. Could be also imL >>>
+ if(lnorth) then
+ jmax = Fjmax_in(g)
+ else
+ jmax = jm_in
+ endif
+
+
+!----------------------------------------------------------------------
+ ndatax =km_in*(jmax+2*nby)*nbx
+ ndatay =km_in*imax*nby
+
+!
+! SEND extended halos toward WEST and EAST
+!
+
+! --- toward WEST ---
+
+ if( itarg_w >= 0) then
+ nebpe = itarg_w
+
+ allocate( sBuf_W(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_W(:,i,j) = W(:,-nbx+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_W, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+
+ end if
+
+! --- toward EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( sBuf_E(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ sBuf_E(:,i,j) = W(:,imax+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_E, ndatax, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+
+ end if
+
+!
+! RECEIVE extended halos from EAST and WEST
+!
+
+! --- from EAST ---
+
+ if( itarg_e >= 0 ) then
+ nebpe = itarg_e
+
+ allocate( rBuf_E(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_E, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ end if
+
+! --- from WEST ---
+
+ if( itarg_w >= 0 ) then
+ nebpe = itarg_w
+
+ allocate( rBuf_W(1:km_in,1:nbx,1-nby:jmax+nby), stat = iaerr )
+ call MPI_IRECV( rBuf_W, ndatax, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ end if
+!
+! Assign received values from WEST and EAST
+!
+
+! From west
+
+ if(lwest) then
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,i,j)= W(:,i,j)+W(:,1-i,j)
+ end do
+ end do
+ else
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,i,j)= W(:,i,j)+rBuf_W(:,i,j)
+ end do
+ end do
+ endif
+
+! From east
+
+ if(least) then
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax-nbx+i,j)= W(:,imax-nbx+i,j)+W(:,imax+1+nbx-i,j)
+ end do
+ end do
+ else
+ do j=1-nby,jmax+nby
+ do i=1,nbx
+ W(:,imax-nbx+i,j)= W(:,imax-nbx+i,j)+rBuf_E(:,i,j)
+ end do
+ end do
+ endif
+
+!
+! SEND halos toward SOUTH and NORTH
+!
+! --- toward SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+ allocate( sBuf_S(1:km_in,1:imax,1:nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_S(:,i,j) = W(:,i,-nby+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_S, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+ end if
+
+! --- toward NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+ allocate( sBuf_N(1:km_in,1:imax,1:nby), stat = iaerr )
+
+ do j=1,nby
+ do i=1,imax
+ sBuf_N(:,i,j)=W(:,i,jmax+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_N, ndatay, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+
+ end if
+
+!
+! RECEIVE halos from NORTH and SOUTH
+!
+!
+! --- from NORTH ---
+
+ if( itarg_n >= 0 ) then
+ nebpe = itarg_n
+
+
+ allocate( rBuf_N(1:km_in,1:imax,1:nby), stat = iaerr )
+ call MPI_IRECV( rBuf_N, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ end if
+
+! --- from SOUTH ---
+
+ if( itarg_s >= 0 ) then
+ nebpe = itarg_s
+
+
+ allocate( rBuf_S(1:km_in,1:imax,1:nby), stat = iaerr )
+ call MPI_IRECV( rBuf_S, ndatay, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+
+ end if
+
+!
+! Assign received values from SOUTH and NORTH
+!
+
+! From south
+
+ if(lsouth) then
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j)= W(:,i,j)+W(:,i,1-j)
+ end do
+ end do
+ else
+ do j=1,nby
+ do i=1,imax
+ W(:,i,j)= W(:,i,j)+rBuf_S(:,i,j)
+ end do
+ end do
+ endif
+
+! From north
+
+ if(lnorth) then
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j)= W(:,i,jmax-nby+j)+W(:,i,jmax+1+nby-j)
+ enddo
+ enddo
+ else
+ do j=1,nby
+ do i=1,imax
+ W(:,i,jmax-nby+j)= W(:,i,jmax-nby+j)+rBuf_N(:,i,j)
+ enddo
+ enddo
+ endif
+
+!-----------------------------------------------------------------------
+
+! DEALLOCATE rBufferes
+
+ deallocate( rBuf_W, stat = iderr)
+ deallocate( rBuf_E, stat = iderr)
+ deallocate( rBuf_S, stat = iderr)
+ deallocate( rBuf_N, stat = iderr)
+
+! DEALLOCATE sBufferes
+
+ if( itarg_w >= 0 ) then
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ end if
+ if( itarg_e >= 0 ) then
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ end if
+ if( itarg_s >= 0 ) then
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ end if
+ if( itarg_n >= 0 ) then
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ end if
+
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+ endif FILT_GRID
+
+!fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+!-----------------------------------------------------------------------
+endsubroutine bocoT_2d_loc
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsend_loc_g12 &
+!***********************************************************************
+! !
+! Upsend data from generation one to generation two !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,V_in,H,km_4_in,flag)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_4_in,flag
+real(r_kind), dimension(km_4_in,1:this%imL,1:this%jmL),intent(in):: V_in
+real(r_kind), dimension(km_4_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_SW,sBuf_SE,sBuf_NW,sBuf_NE &
+ ,rBuf_SW,rBuf_SE,rBuf_NW,rBuf_NE
+
+real(r_kind),dimension(1:km_4_in,1:this%imL,1:this%jmL):: dBuf_SW
+real(r_kind),dimension(1:km_4_in,1:this%imL,1:this%jmL):: dBuf_SE
+real(r_kind),dimension(1:km_4_in,1:this%imL,1:this%jmL):: dBuf_NW
+real(r_kind),dimension(1:km_4_in,1:this%imL,1:this%jmL):: dBuf_NE
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,ndata,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind):: mygen_dn,mygen_up
+integer(i_kind):: itarg_up
+logical:: lsendup_sw,lsendup_se,lsendup_nw,lsendup_ne
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+ mygen_dn=1
+ mygen_up=2
+!
+! Define generational flags
+!
+
+ itarg_up=Fitargup_loc12(flag)
+
+ lsendup_sw = lsendup_sw_loc
+ lsendup_se = lsendup_se_loc
+ lsendup_nw = lsendup_nw_loc
+ lsendup_ne = lsendup_ne_loc
+!-----------------------------------------------------------------------
+
+!N if(my_hgen==mygen_up) then
+ H(:,:,:) = 0.0d0
+!N endif
+
+ ndata =km_4_in*imL*jmL
+
+!
+! --- Send data to SW portion of processors at higher generation
+!
+
+ if( lsendup_sw ) then
+
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_SW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_SW(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SW, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+ call MPI_WAIT( sHandle(1), istat, ierr )
+
+ deallocate( sBuf_SW, stat = ierr )
+
+ endif
+
+ endif
+!
+! --- Receive SW portion of data at higher generation
+!
+
+!N if( my_hgen==mygen_up .and. itargdn_sw_loc21 >= 0 ) then
+ if( itargdn_sw_loc21 >= 0 ) then
+
+ nebpe = itargdn_sw_loc21
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_SW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,i,j)=dBuf_SW(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!
+! --- Send data to SE portion of processors at higher generation
+!
+
+ if( lsendup_se ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_SE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_SE(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SE, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+ call MPI_WAIT( sHandle(2), istat, ierr )
+
+ deallocate( sBuf_SE, stat = ierr )
+
+ endif
+
+ end if
+
+!
+! --- Receive SE portion of data at higher generation
+!
+
+!N if( my_hgen==mygen_up .and. itargdn_se_loc21 >= 0 ) then
+ if( itargdn_se_loc21 >= 0 ) then
+
+ nebpe = itargdn_se_loc21
+
+ if(nebpe /= mype) then
+
+ call MPI_IRECV( dBuf_SE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ endif
+ do j=1,jmL
+ do i=1,imL
+ H(:,imL+i,j)=dBuf_SE(:,i,j)
+ enddo
+ enddo
+
+ endif
+!
+! --- Send data to NW portion of processors at higher generation
+!
+
+ if( lsendup_nw ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_NW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_NW(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NW, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(3), isend)
+
+ call MPI_WAIT( sHandle(3), istat, ierr )
+
+ deallocate( sBuf_NW, stat = ierr )
+
+ end if
+
+ end if
+
+!
+! --- Receive NW portion of data at higher generation
+!
+
+! if( my_hgen==mygen_up .and. itargdn_nw_loc21 >= 0 ) then
+ if( itargdn_nw_loc21 >= 0 ) then
+
+ nebpe = itargdn_nw_loc21
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_NW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,i,jmL+j)=dBuf_NW(:,i,j)
+ enddo
+ enddo
+
+ endif
+!
+! --- Send data to NE portion of processors at higher generation
+!
+
+ if( lsendup_ne ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_NE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_NE(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NE, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(4), isend)
+ call MPI_WAIT( sHandle(4), istat, ierr )
+
+ deallocate( sBuf_NE, stat = ierr )
+
+ endif
+
+ end if
+
+!
+! --- Receive NE portion of data at higher generation
+!
+
+!N if( my_hgen==mygen_up .and. itargdn_ne_loc21 >= 0 ) then
+ if( itargdn_ne_loc21 >= 0 ) then
+
+ nebpe = itargdn_ne_loc21
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_NE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,imL+i,jmL+j)=dBuf_NE(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+!-----------------------------------------------------------------------
+endsubroutine upsend_loc_g12
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsend_loc_g23 &
+!***********************************************************************
+! !
+! Upsend data from generation three to generation four !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,V_in,H,km_16_in,flag)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_16_in,flag
+real(r_kind), dimension(km_16_in,1:this%imL,1:this%jmL),intent(in):: V_in
+real(r_kind), dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_SW,sBuf_SE,sBuf_NW,sBuf_NE &
+ ,rBuf_SW,rBuf_SE,rBuf_NW,rBuf_NE
+
+real(r_kind),dimension(1:km_16_in,1:this%imL,1:this%jmL):: dBuf_SW
+real(r_kind),dimension(1:km_16_in,1:this%imL,1:this%jmL):: dBuf_SE
+real(r_kind),dimension(1:km_16_in,1:this%imL,1:this%jmL):: dBuf_NW
+real(r_kind),dimension(1:km_16_in,1:this%imL,1:this%jmL):: dBuf_NE
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,ndata,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind):: mygen_dn,mygen_up
+integer(i_kind):: itarg_up
+logical:: lsendup_sw,lsendup_se,lsendup_nw,lsendup_ne
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+ mygen_dn=2
+ mygen_up=3
+!
+! Define generational flags
+!
+
+ itarg_up=Fitargup_loc23(flag)
+
+ lsendup_sw = lsendup_sw_loc
+ lsendup_se = lsendup_se_loc
+ lsendup_nw = lsendup_nw_loc
+ lsendup_ne = lsendup_ne_loc
+!-----------------------------------------------------------------------
+
+!N if(my_hgen==mygen_up) then
+ H(:,:,:) = 0.0d0
+!N endif
+
+ ndata =km_16_in*imL*jmL
+
+!
+! --- Send data to SW portion of processors at higher generation
+!
+
+ if( lsendup_sw ) then
+
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_SW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_SW(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SW, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+ call MPI_WAIT( sHandle(1), istat, ierr )
+
+ deallocate( sBuf_SW, stat = ierr )
+
+ endif
+
+ endif
+!
+! --- Receive SW portion of data at higher generation
+!
+
+!N if( my_hgen==mygen_up .and. itargdn_sw_loc32 >= 0 ) then
+ if( itargdn_sw_loc32 >= 0 ) then
+
+ nebpe = itargdn_sw_loc32
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_SW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,i,j)=dBuf_SW(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!
+! --- Send data to SE portion of processors at higher generation
+!
+
+ if( lsendup_se ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_SE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_SE(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SE, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+ call MPI_WAIT( sHandle(2), istat, ierr )
+
+ deallocate( sBuf_SE, stat = ierr )
+
+ endif
+
+ end if
+
+!
+! --- Receive SE portion of data at higher generation
+!
+
+!N if( my_hgen==mygen_up .and. itargdn_se_loc32 >= 0 ) then
+ if( itargdn_se_loc32 >= 0 ) then
+
+ nebpe = itargdn_se_loc32
+
+ if(nebpe /= mype) then
+
+ call MPI_IRECV( dBuf_SE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ endif
+ do j=1,jmL
+ do i=1,imL
+ H(:,imL+i,j)=dBuf_SE(:,i,j)
+ enddo
+ enddo
+
+ endif
+!
+! --- Send data to NW portion of processors at higher generation
+!
+
+ if( lsendup_nw ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_NW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_NW(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NW, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(3), isend)
+
+ call MPI_WAIT( sHandle(3), istat, ierr )
+
+ deallocate( sBuf_NW, stat = ierr )
+
+ end if
+
+ end if
+
+!
+! --- Receive NW portion of data at higher generation
+!
+
+! if( my_hgen==mygen_up .and. itargdn_nw_loc32 >= 0 ) then
+ if( itargdn_nw_loc32 >= 0 ) then
+
+ nebpe = itargdn_nw_loc32
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_NW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,i,jmL+j)=dBuf_NW(:,i,j)
+ enddo
+ enddo
+
+ endif
+!
+! --- Send data to NE portion of processors at higher generation
+!
+
+ if( lsendup_ne ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_NE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_NE(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NE, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(4), isend)
+ call MPI_WAIT( sHandle(4), istat, ierr )
+
+ deallocate( sBuf_NE, stat = ierr )
+
+ endif
+
+ end if
+
+!
+! --- Receive NE portion of data at higher generation
+!
+
+!N if( my_hgen==mygen_up .and. itargdn_ne_loc32 >= 0 ) then
+ if( itargdn_ne_loc32 >= 0 ) then
+
+ nebpe = itargdn_ne_loc32
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_NE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,imL+i,jmL+j)=dBuf_NE(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+!-----------------------------------------------------------------------
+endsubroutine upsend_loc_g23
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsend_loc_g34 &
+!***********************************************************************
+! !
+! Upsend data from generation three to generation four !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,V_in,H,km_64_in,flag)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_64_in,flag
+real(r_kind), dimension(km_64_in,1:this%imL,1:this%jmL),intent(in):: V_in
+real(r_kind), dimension(km_64_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_SW,sBuf_SE,sBuf_NW,sBuf_NE &
+ ,rBuf_SW,rBuf_SE,rBuf_NW,rBuf_NE
+
+real(r_kind),dimension(1:km_64_in,1:this%imL,1:this%jmL):: dBuf_SW
+real(r_kind),dimension(1:km_64_in,1:this%imL,1:this%jmL):: dBuf_SE
+real(r_kind),dimension(1:km_64_in,1:this%imL,1:this%jmL):: dBuf_NW
+real(r_kind),dimension(1:km_64_in,1:this%imL,1:this%jmL):: dBuf_NE
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,ndata,i,j
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind):: mygen_dn,mygen_up
+integer(i_kind):: itarg_up
+logical:: lsendup_sw,lsendup_se,lsendup_nw,lsendup_ne
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+ mygen_dn=3
+ mygen_up=4
+!
+! Define generational flags
+!
+
+ itarg_up=Fitargup_loc34(flag)
+
+ lsendup_sw = lsendup_sw_loc
+ lsendup_se = lsendup_se_loc
+ lsendup_nw = lsendup_nw_loc
+ lsendup_ne = lsendup_ne_loc
+!-----------------------------------------------------------------------
+
+!N if(my_hgen==mygen_up) then
+ H(:,:,:) = 0.0d0
+!N endif
+
+ ndata =km_64_in*imL*jmL
+
+!
+! --- Send data to SW portion of processors at higher generation
+!
+
+ if( lsendup_sw ) then
+
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_SW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_SW(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SW, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(1), isend)
+ call MPI_WAIT( sHandle(1), istat, ierr )
+
+ deallocate( sBuf_SW, stat = ierr )
+
+ endif
+
+ endif
+!
+! --- Receive SW portion of data at higher generation
+!
+
+ if( itargdn_sw_loc43 >= 0 ) then
+
+ nebpe = itargdn_sw_loc43
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_SW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,i,j)=dBuf_SW(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+!
+! --- Send data to SE portion of processors at higher generation
+!
+
+ if( lsendup_se ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_SE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_SE(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SE, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(2), isend)
+ call MPI_WAIT( sHandle(2), istat, ierr )
+
+ deallocate( sBuf_SE, stat = ierr )
+
+ endif
+
+ end if
+
+!
+! --- Receive SE portion of data at higher generation
+!
+
+ if( itargdn_se_loc43 >= 0 ) then
+
+ nebpe = itargdn_se_loc43
+
+ if(nebpe /= mype) then
+
+ call MPI_IRECV( dBuf_SE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ endif
+ do j=1,jmL
+ do i=1,imL
+ H(:,imL+i,j)=dBuf_SE(:,i,j)
+ enddo
+ enddo
+
+ endif
+!
+! --- Send data to NW portion of processors at higher generation
+!
+
+ if( lsendup_nw ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_NW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_NW(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NW(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NW, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(3), isend)
+
+ call MPI_WAIT( sHandle(3), istat, ierr )
+
+ deallocate( sBuf_NW, stat = ierr )
+
+ end if
+
+ end if
+
+!
+! --- Receive NW portion of data at higher generation
+!
+
+! if( my_hgen==mygen_up .and. itargdn_nw_loc43 >= 0 ) then
+ if( itargdn_nw_loc43 >= 0 ) then
+
+ nebpe = itargdn_nw_loc43
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_NW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,i,jmL+j)=dBuf_NW(:,i,j)
+ enddo
+ enddo
+
+ endif
+!
+! --- Send data to NE portion of processors at higher generation
+!
+
+ if( lsendup_ne ) then
+ nebpe = itarg_up
+
+ if(nebpe == mype) then
+
+ do j=1,jmL
+ do i=1,imL
+ dBuf_NE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ else
+
+ allocate( sBuf_NE(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NE(:,i,j) = V_in(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NE, ndata, dtype, nebpe, mype, &
+ mpi_comm_comp, sHandle(4), isend)
+ call MPI_WAIT( sHandle(4), istat, ierr )
+
+ deallocate( sBuf_NE, stat = ierr )
+
+ endif
+
+ end if
+
+!
+! --- Receive NE portion of data at higher generation
+!
+
+!N if( my_hgen==mygen_up .and. itargdn_ne_loc43 >= 0 ) then
+ if( itargdn_ne_loc43 >= 0 ) then
+
+ nebpe = itargdn_ne_loc43
+
+ if(nebpe /= mype) then
+ call MPI_IRECV( dBuf_NE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_comp, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+ endif
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,imL+i,jmL+j)=dBuf_NE(:,i,j)
+ enddo
+ enddo
+
+ endif
+
+
+!-----------------------------------------------------------------------
+endsubroutine upsend_loc_g34
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsend_loc_g43 &
+!***********************************************************************
+! *
+! Downsending data from low resolution pes (mygen_up) *
+! to the concurent high-resolution pes (mygen_dn) *
+! and add the existing and the recevied values *
+! !
+! - offset version - !
+! *
+!***********************************************************************
+(this,W,Z,km_64_in,flag)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_64_in,flag
+real(r_kind), dimension(km_64_in,1:this%im,1:this%jm),intent(in):: W
+real(r_kind), dimension(km_64_in,1:this%imL,1:this%jmL),intent(out):: Z
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_SW,sBuf_SE,sBuf_NW,sBuf_NE &
+ ,rBuf_SW,rBuf_SE,rBuf_NW,rBuf_NE
+
+real(r_kind),dimension(1:km_64_in,1:this%imL,1:this%jmL):: dBuf_SW
+real(r_kind),dimension(1:km_64_in,1:this%imL,1:this%jmL):: dBuf_SE
+real(r_kind),dimension(1:km_64_in,1:this%imL,1:this%jmL):: dBuf_NW
+real(r_kind),dimension(1:km_64_in,1:this%imL,1:this%jmL):: dBuf_NE
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,ndata,i,j,L
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind):: itarg_up
+logical:: lsendup_sw,lsendup_se,lsendup_nw,lsendup_ne
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+
+ Z(:,:,:) = 0.0d0
+!
+! Define generational flags
+!
+
+ itarg_up=Fitargup_loc34(flag)
+
+ ndata =km_64_in*imL*jmL
+
+!
+! --- Send data from SW portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ if(itargdn_sw_loc43 >= 0) then
+
+ nebpe = itargdn_sw_loc43
+
+
+ allocate( sBuf_SW(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SW(:,i,j) = W(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SW, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_SW, stat = ierr )
+
+ endif
+
+!
+! --- Receive SW portion of data at lower generation
+
+
+ if( lsendup_sw ) then
+
+ nebpe = itarg_up
+
+
+ allocate( rBuf_SW(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_SW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Z(:,i,j)=rBuf_SW(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_SW, stat = iderr)
+
+ endif
+
+!
+! --- Send data from SE portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ if(itargdn_se_loc43 >= 0) then
+
+ nebpe = itargdn_se_loc43
+
+ allocate( sBuf_SE(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SE(:,i,j) = W(:,imL+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SE, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_SE, stat = ierr )
+
+ endif
+!
+! --- Receive SE portion of data at lower generation
+
+
+ if( lsendup_se ) then
+ nebpe = itarg_up
+
+
+ allocate( rBuf_SE(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_SE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Z(:,i,j)=Rbuf_SE(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_SE, stat = iderr)
+
+ end if
+
+!
+! --- Send data from NW portion of processors at the higher generation
+! to corresponding PE's at lower generantion
+
+ if(itargdn_nw_loc43 >= 0) then
+
+ nebpe = itargdn_nw_loc43
+
+
+ allocate( sBuf_NW(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NW(:,i,j) = W(:,i,jmL+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NW, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_NW, stat = ierr )
+
+ endif
+
+!
+! --- Receive NW portion of data at lower generation
+
+
+ if( lsendup_nw ) then
+
+ nebpe = itarg_up
+
+ allocate( rBuf_NW(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_NW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Z(:,i,j)=Rbuf_NW(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_NW, stat = iderr)
+
+
+ end if
+
+
+! --- Send data from NE portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ if(itargdn_ne_loc43 >= 0) then
+
+ nebpe = itargdn_ne_loc43
+
+ allocate( sBuf_NE(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NE(:,i,j) = W(:,imL+i,jmL+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NE, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_NE, stat = ierr )
+
+ endif
+
+!
+! --- Receive NE portion of data at lower generation
+!
+
+ if( lsendup_ne ) then
+ nebpe = itarg_up
+
+ allocate( rBuf_NE(1:km_64_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_NE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ Z(:,i,j)=rBuf_NE(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_NE, stat = iderr)
+
+ end if
+
+!-----------------------------------------------------------------------
+endsubroutine downsend_loc_g43
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsend_loc_g32 &
+!***********************************************************************
+! *
+! Downsending data from low resolution pes (mygen_up) *
+! to the concurent high-resolution pes (mygen_dn) *
+! and add the existing and the recevied values *
+! !
+! - offset version - !
+! *
+!***********************************************************************
+(this,Z,H,km_16_in,flag)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_16_in,flag
+real(r_kind), dimension(km_16_in,1:this%im,1:this%jm),intent(in):: Z
+real(r_kind), dimension(km_16_in,1:this%imL,1:this%jmL),intent(out):: H
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_SW,sBuf_SE,sBuf_NW,sBuf_NE &
+ ,rBuf_SW,rBuf_SE,rBuf_NW,rBuf_NE
+
+real(r_kind),dimension(1:km_16_in,1:this%imL,1:this%jmL):: dBuf_SW
+real(r_kind),dimension(1:km_16_in,1:this%imL,1:this%jmL):: dBuf_SE
+real(r_kind),dimension(1:km_16_in,1:this%imL,1:this%jmL):: dBuf_NW
+real(r_kind),dimension(1:km_16_in,1:this%imL,1:this%jmL):: dBuf_NE
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,ndata,i,j,L
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind):: itarg_up
+logical:: lsendup_sw,lsendup_se,lsendup_nw,lsendup_ne
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+
+ H(:,:,:) = 0.0d0
+!
+! Define generational flags
+!
+
+ itarg_up=Fitargup_loc23(flag)
+
+ ndata =km_16_in*imL*jmL
+
+!
+! --- Send data from SW portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+
+ if( itargdn_sw_loc32 >= 0 ) then
+
+ nebpe = itargdn_sw_loc32
+
+
+ allocate( sBuf_SW(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SW(:,i,j) = Z(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SW, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_SW, stat = ierr )
+
+ endif
+
+!
+! --- Receive SW portion of data at lower generation
+
+
+ if( lsendup_sw ) then
+
+ nebpe = itarg_up
+
+
+ allocate( rBuf_SW(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_SW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,i,j)=rBuf_SW(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_SW, stat = iderr)
+
+ endif
+
+!
+! --- Send data from SE portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ if( itargdn_se_loc32 >= 0 ) then
+
+ nebpe = itargdn_se_loc32
+
+ allocate( sBuf_SE(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SE(:,i,j) = Z(:,imL+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SE, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_SE, stat = ierr )
+
+
+ endif
+!
+! --- Receive SE portion of data at lower generation
+
+
+ if( lsendup_se ) then
+ nebpe = itarg_up
+
+
+ allocate( rBuf_SE(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_SE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,i,j)=Rbuf_SE(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_SE, stat = iderr)
+
+ end if
+
+!
+! --- Send data from NW portion of processors at the higher generation
+! to corresponding PE's at lower generantion
+
+ if( itargdn_nw_loc32 >= 0 ) then
+
+ nebpe = itargdn_nw_loc32
+
+
+ allocate( sBuf_NW(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NW(:,i,j) = Z(:,i,jmL+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NW, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_NW, stat = ierr )
+
+
+ endif
+!
+! --- Receive NW portion of data at lower generation
+
+
+ if( lsendup_nw ) then
+
+ nebpe = itarg_up
+
+ allocate( rBuf_NW(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_NW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,i,j)=Rbuf_NW(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_NW, stat = iderr)
+
+
+ end if
+
+
+! --- Send data from NE portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ if( itargdn_ne_loc32 >= 0 ) then
+ nebpe = itargdn_ne_loc32
+
+
+ allocate( sBuf_NE(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NE(:,i,j) = Z(:,imL+i,jmL+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NE, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_NE, stat = ierr )
+
+ endif
+!
+! --- Receive NE portion of data at lower generation
+!
+
+ if( lsendup_ne ) then
+ nebpe = itarg_up
+
+ allocate( rBuf_NE(1:km_16_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_NE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ H(:,i,j)=rBuf_NE(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_NE, stat = iderr)
+
+ end if
+
+!-----------------------------------------------------------------------
+endsubroutine downsend_loc_g32
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsend_loc_g21 &
+!***********************************************************************
+! *
+! Downsending data from low resolution pes (mygen_up) *
+! to the concurent high-resolution pes (mygen_dn) *
+! and add the existing and the recevied values *
+! !
+! - offset version - !
+! *
+!***********************************************************************
+(this,H,V_out,km_4_in,flag)
+!-----------------------------------------------------------------------
+use mpi
+implicit none
+class(mg_intstate_type),target::this
+!-----------------------------------------------------------------------
+integer(i_kind), intent(in):: km_4_in,flag
+real(r_kind), dimension(km_4_in,1:this%im,1:this%jm),intent(in):: H
+real(r_kind), dimension(km_4_in,1:this%imL,1:this%jmL),intent(out):: V_out
+!-----------------------------------------------------------------------
+real(r_kind), allocatable, dimension(:,:,:):: &
+ sBuf_SW,sBuf_SE,sBuf_NW,sBuf_NE &
+ ,rBuf_SW,rBuf_SE,rBuf_NW,rBuf_NE
+
+real(r_kind),dimension(1:km_4_in,1:this%imL,1:this%jmL):: dBuf_SW
+real(r_kind),dimension(1:km_4_in,1:this%imL,1:this%jmL):: dBuf_SE
+real(r_kind),dimension(1:km_4_in,1:this%imL,1:this%jmL):: dBuf_NW
+real(r_kind),dimension(1:km_4_in,1:this%imL,1:this%jmL):: dBuf_NE
+
+integer(i_kind) sHandle(4),rHandle(4),ISTAT(MPI_STATUS_SIZE)
+integer(i_kind) iaerr,ierr,iderr,ndata,i,j,L
+integer(i_kind) isend,irecv,nebpe
+integer(i_kind):: itarg_up
+logical:: lsendup_sw,lsendup_se,lsendup_nw,lsendup_ne
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+
+ V_out(:,:,:) = 0.0d0
+!
+! Define generational flags
+!
+
+ itarg_up=Fitargup_loc12(flag)
+
+ ndata =km_4_in*imL*jmL
+
+!
+! --- Send data from SW portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+
+ if( itargdn_sw_loc21 >= 0 ) then
+ nebpe = itargdn_sw_loc21
+
+
+ allocate( sBuf_SW(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SW(:,i,j) = H(:,i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SW, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(1), isend)
+ call MPI_WAIT( sHandle(1), istat, ierr )
+ deallocate( sBuf_SW, stat = ierr )
+
+ endif
+
+!
+! --- Receive SW portion of data at lower generation
+!
+
+
+ if( lsendup_sw ) then
+
+ nebpe = itarg_up
+
+
+ allocate( rBuf_SW(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_SW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(1), irecv)
+ call MPI_WAIT( rHandle(1), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ V_out(:,i,j)=rBuf_SW(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_SW, stat = iderr)
+
+ endif
+
+!
+! --- Send data from SE portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ if( itargdn_se_loc21 >= 0 ) then
+ nebpe = itargdn_se_loc21
+
+ allocate( sBuf_SE(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_SE(:,i,j) = H(:,imL+i,j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_SE, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(2), isend)
+ call MPI_WAIT( sHandle(2), istat, ierr )
+ deallocate( sBuf_SE, stat = ierr )
+
+
+ endif
+!
+! --- Receive SE portion of data at lower generation
+
+
+ if( lsendup_se ) then
+ nebpe = itarg_up
+
+
+ allocate( rBuf_SE(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_SE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(2), irecv)
+ call MPI_WAIT( rHandle(2), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ V_out(:,i,j)=Rbuf_SE(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_SE, stat = iderr)
+
+ end if
+
+!
+! --- Send data from NW portion of processors at the higher generation
+! to corresponding PE's at lower generantion
+
+ if( itargdn_nw_loc21 >= 0 ) then
+
+ nebpe = itargdn_nw_loc21
+
+
+ allocate( sBuf_NW(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NW(:,i,j) = H(:,i,jmL+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NW, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(3), isend)
+ call MPI_WAIT( sHandle(3), istat, ierr )
+ deallocate( sBuf_NW, stat = ierr )
+
+
+ endif
+!
+! --- Receive NW portion of data at lower generation
+
+
+ if( lsendup_nw ) then
+
+ nebpe = itarg_up
+
+ allocate( rBuf_NW(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_NW, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(3), irecv)
+ call MPI_WAIT( rHandle(3), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ V_out(:,i,j)=Rbuf_NW(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_NW, stat = iderr)
+
+
+ end if
+
+
+! --- Send data from NE portion of processors at the higher generation
+! to corresponding PE's at lower generation
+
+ if( itargdn_ne_loc21 >= 0 ) then
+
+ nebpe = itargdn_ne_loc21
+
+
+ allocate( sBuf_NE(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ do j=1,jmL
+ do i=1,imL
+ sBuf_NE(:,i,j) = H(:,imL+i,jmL+j)
+ enddo
+ enddo
+
+ call MPI_ISEND( sBuf_NE, ndata, dtype, nebpe, mype, &
+ mpi_comm_work, sHandle(4), isend)
+ call MPI_WAIT( sHandle(4), istat, ierr )
+ deallocate( sBuf_NE, stat = ierr )
+
+
+ endif
+!
+! --- Receive NE portion of data at lower generation
+!
+
+ if( lsendup_ne ) then
+
+ nebpe = itarg_up
+
+ allocate( rBuf_NE(1:km_4_in,1:imL,1:jmL), stat = iaerr )
+
+ call MPI_IRECV( rBuf_NE, ndata, dtype, nebpe, nebpe, &
+ mpi_comm_work, rHandle(4), irecv)
+ call MPI_WAIT( rHandle(4), istat, ierr )
+
+ do j=1,jmL
+ do i=1,imL
+ V_out(:,i,j)=rBuf_NE(:,i,j)
+ enddo
+ enddo
+
+ deallocate( rBuf_NE, stat = iderr)
+
+ end if
+
+!-----------------------------------------------------------------------
+endsubroutine downsend_loc_g21
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+end submodule mg_bocos
diff --git a/src/mgbf/mg_domain.f90 b/src/mgbf/mg_domain.f90
new file mode 100644
index 0000000000..d56d1a5f9f
--- /dev/null
+++ b/src/mgbf/mg_domain.f90
@@ -0,0 +1,644 @@
+submodule(mg_parameter) mg_domain
+!$$$ submodule documentation block
+! . . . .
+! module: mg_domain
+! prgmmr: rancic org: NCEP/EMC date: 2020
+!
+! abstract: Definition of a squared integration domain
+!
+! module history log:
+! 2023-04-19 lei - object-oriented coding
+! 2024-01-11 rancic - optimization for ensemble localization
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! init_mg_domain -
+! init_domain -
+! init_topology_2d -
+! real_itarg -
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+use kinds, only: i_kind
+
+implicit none
+
+!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+contains
+!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine init_mg_domain(this)
+!***********************************************************************
+! *
+! Initialize square domain *
+! *
+!***********************************************************************
+implicit none
+class(mg_parameter_type)::this
+
+call init_domain(this)
+call init_topology_2d(this)
+
+!-----------------------------------------------------------------------
+endsubroutine init_mg_domain
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine init_domain(this)
+!***********************************************************************
+! *
+! Definition of constants that control filtering domain *
+! *
+!***********************************************************************
+implicit none
+class(mg_parameter_type),target::this
+
+integer(i_kind) n,nstrd,i,j
+logical:: F=.false., T=.true.
+
+integer(i_kind):: loc_pe,g
+include "type_parameter_locpointer.inc"
+include "type_parameter_point2this.inc"
+!-----------------------------------------------------------------------
+
+ Flwest(1)=nx.eq.1
+ Fleast(1)=nx.eq.nxm
+ Flsouth(1)=my.eq.1
+ Flnorth(1)=my.eq.nym
+
+ if(l_hgen) then
+
+ loc_pe=mype_hgen-maxpe_fgen(my_hgen-1)
+ jy=loc_pe/ixm(my_hgen)+1
+ ix=mod(loc_pe,ixm(my_hgen))+1
+
+ Flwest(2)=ix.eq.1
+ Fleast(2)=ix.eq.ixm(my_hgen)
+ Flsouth(2)=jy.eq.1
+ Flnorth(2)=jy.eq.jym(my_hgen)
+
+ else
+
+ jy = -1
+ ix = -1
+
+ Flwest(2)=F
+ Fleast(2)=F
+ Flsouth(2)=F
+ Flnorth(2)=F
+
+ endif
+
+ mype_filt(1)=mype
+ mype_filt(2)=mype_hgen
+
+!
+! Communication params for analysis grid
+!
+ if(nx==1) then
+ itarg_wA=-1
+ else
+ itarg_wA=mype-1
+ endif
+
+ if(nx==nxm) then
+ itarg_eA=-1
+ else
+ itarg_eA=mype+1
+ endif
+
+ if(my==1) then
+ itarg_sA=-1
+ else
+ itarg_sA=mype-nxm
+ endif
+
+ if(my==nym) then
+ itarg_nA=-1
+ else
+ itarg_nA=mype+nxm
+ endif
+
+ lwestA=nx.eq.1
+ leastA=nx.eq.nxm
+ lsouthA=my.eq.1
+ lnorthA=my.eq.nym
+
+
+!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+! write(100+mype,'(a)')'---------------------------------'
+! write(100+mype,'(a)')'From init_domain'
+! write(100+mype,'(a,2i5)')'mype=',mype
+! write(100+mype,'(a,i5)')'nx=',nx
+! write(100+mype,'(a,i5)')'my=',my
+! write(100+mype,'(a)')'---------------------------------'
+! write(100+mype_filt,'(a)')'---------------------------------'
+! write(100+mype_filt,'(a,3i5)')'mype,mype_filt,mygen :',mype,mype_filt,mygen
+! write(100+mype_filt,'(a,2i5)')'ix,jy= ',ix,jy
+! write(100+mype_filt,'(a,l5)')'lwest = ',lwest
+! write(100+mype_filt,'(a,l5)')'least = ',least
+! write(100+mype_filt,'(a,l5)')'lsouth= ',lsouth
+! write(100+mype_filt,'(a,l5)')'lnorth= ',lnorth
+! write(100+mype_filt,'(a,l5)')'lcorner_sw ',lcorner_sw
+! write(100+mype_filt,'(a,l5)')'lcorner_se ',lcorner_se
+! write(100+mype_filt,'(a,l5)')'lcorner_nw ',lcorner_nw
+! write(100+mype_filt,'(a,l5)')'lcorner_ne ',lcorner_ne
+! write(100+mype_filt,'(a)')'----------------------------------'
+! write(100+mype_filt,'(a)')' '
+!-----------------------------------------------------------------------
+! if(mype==0) then
+! write(27,'(a,i4)') 'nb=',nb
+! write(27,'(a,i4)') 'mb=',mb
+! endif
+!
+! call finishMPI
+!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+!-----------------------------------------------------------------------
+endsubroutine init_domain
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine init_topology_2d(this)
+!***********************************************************************
+! *
+! Define topology of filter grid *
+! - Four generations - *
+! *
+!***********************************************************************
+implicit none
+class(mg_parameter_type),target::this
+!-----------------------------------------------------------------------
+logical:: F=.false., T=.true.
+
+integer(i_kind) mx2,my2,ix_up,jy_up,ix_dn,jy_dn
+integer(i_kind) g,naux,nx_up,my_up
+include "type_parameter_locpointer.inc"
+include "type_parameter_point2this.inc"
+!-----------------------------------------------------------------------
+!
+! Topology of generations of the squared domain
+!
+! G1
+! _____ _____ _____ _____ _____ _____ _____ _____
+! | | | | | | | | |
+! | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
+! |_____|_____|_____|_____|_____|_____|_____|_____|
+! | | | | | | | | |
+! | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
+! |_____|_____|_____|_____|_____|_____|_____|_____|
+! | | | | | | | | |
+! | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
+! |_____|_____|_____|_____|_____|_____|_____|_____|
+! | | | | | | | | |
+! | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
+! |_____|_____|_____|_____|_____|_____|_____|_____|
+! | | | | | | | | |
+! | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
+! |_____|_____|_____|_____|_____|_____|_____|_____|
+! | | | | | | | | |
+! | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
+! |_____|_____|_____|_____|_____|_____|_____|_____|
+! | | | | | | | | |
+! | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
+! |_____|_____|_____|_____|_____|_____|_____|_____|
+! | | | | | | | | |
+! | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+! |_____|_____|_____|_____|_____|_____|_____|_____|
+!
+!
+! G2
+! ___________ ___________ ___________ ___________
+! | | | | |
+! | | | | |
+! | 76 | 77 | 78 | 79 |
+! | | | | |
+! | | | | |
+! |___________|___________|___________|___________|
+! | | | | |
+! | | | | |
+! | 72 | 73 | 74 | 75 |
+! | | | | |
+! | | | | |
+! |___________|___________|___________|___________|
+! | | | | |
+! | | | | |
+! | 68 | 69 | 70 | 71 |
+! | | | | |
+! | | | | |
+! |___________|___________|___________|___________|
+! | | | | |
+! | | | | |
+! | 64 | 65 | 66 | 67 |
+! | | | | |
+! | | | | |
+! |___________|___________|___________|___________|
+!
+!
+! G3
+! _______________________ _______________________
+! | | |
+! | | |
+! | | |
+! | | |
+! | | |
+! | 82 | 83 |
+! | | |
+! | | |
+! | | |
+! | | |
+! | | |
+! |_______________________|_______________________|
+! | | |
+! | | |
+! | | |
+! | | |
+! | | |
+! | 80 | 81 |
+! | | |
+! | | |
+! | | |
+! | | |
+! | | |
+! |_______________________|_______________________|
+!
+!
+! G4
+! _______________________________________________
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | 84 |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! | |
+! |_______________________________________________|
+!
+!----------------------------------------------------------------------
+
+ do g = 1,2
+!***
+!*** Send WEST
+!***
+ if(Flwest(g)) then
+ Fitarg_w(g) = -1
+ else
+ if(g==1.or.l_hgen) then
+ Fitarg_w(g) = mype_filt(g)-1
+ else
+ Fitarg_w(g) = -1
+ endif
+ endif
+!***
+!*** Send EAST
+!***
+ if(Fleast(g)) then
+ Fitarg_e(g) = -1
+ else
+ if(g==1.or.l_hgen) then
+ Fitarg_e(g) = mype_filt(g)+1
+ else
+ Fitarg_e(g) = -1
+ endif
+ endif
+
+!***
+!*** Send SOUTH
+!***
+
+ if(Flsouth(g)) then
+ Fitarg_s(g)=-1
+ else
+ select case(g)
+ case(1)
+ naux = nxm
+ case(2)
+ if(l_hgen) then
+ naux = ixm(my_hgen)
+ endif
+ endselect
+ if(g==1.or.l_hgen) then
+ Fitarg_s(g)=mype_filt(g)-naux
+ else
+ Fitarg_s(g)=-1
+ endif
+ endif
+
+!***
+!*** Send NORTH
+!***
+ if(Flnorth(g)) then
+ Fitarg_n(g)=-1
+ else
+ select case(g)
+ case(1)
+ naux = nxm
+ case(2)
+ if(l_hgen) then
+ naux = ixm(my_hgen)
+ endif
+ endselect
+ if(g==1.or.l_hgen) then
+ Fitarg_n(g)=mype_filt(g)+naux
+ else
+ Fitarg_n(g)=-1
+ endif
+ endif
+
+!***
+!*** Send SOUTH-WEST
+!***
+
+ if(Flsouth(g).and.Flwest(g)) then
+ Fitarg_sw(g)=-1
+ else &
+ if(Flsouth(g)) then
+ Fitarg_sw(g)=Fitarg_w(g)
+ else &
+ if(Flwest(g)) then
+ Fitarg_sw(g)=Fitarg_s(g)
+ else
+ Fitarg_sw(g)=Fitarg_s(g)-1
+ endif
+ if(g>1 .and. .not.l_hgen) then
+ Fitarg_sw(g)=-1
+ endif
+
+!***
+!*** Send SOUTH-EAST
+!***
+
+ if(Flsouth(g).and.Fleast(g)) then
+ Fitarg_se(g)=-1
+ else &
+ if(Flsouth(g)) then
+ Fitarg_se(g)=Fitarg_e(g)
+ else &
+ if(Fleast(g)) then
+ Fitarg_se(g)=Fitarg_s(g)
+ else
+ Fitarg_se(g)=Fitarg_s(g)+1
+ endif
+ if(g>1 .and. .not.l_hgen) then
+ Fitarg_se(g)=-1
+ endif
+
+!***
+!*** Send NORTH-WEST
+!***
+ if(Flnorth(g).and.Flwest(g)) then
+ Fitarg_nw(g)=-1
+ else &
+ if(Flnorth(g)) then
+ Fitarg_nw(g)=Fitarg_w(g)
+ else &
+ if(Flwest(g)) then
+ Fitarg_nw(g)=Fitarg_n(g)
+ else
+ Fitarg_nw(g)=Fitarg_n(g)-1
+ endif
+ if(g>1 .and. .not.l_hgen) then
+ Fitarg_nw(g)=-1
+ endif
+
+
+!***
+!*** Send NORTH-EAST
+!***
+
+ if(Flnorth(g).and.Fleast(g)) then
+ Fitarg_ne(g)=-1
+ else &
+ if(Flnorth(g)) then
+ Fitarg_ne(g)=Fitarg_e(g)
+ else &
+ if(Fleast(g)) then
+ Fitarg_ne(g)=Fitarg_n(g)
+ else
+ Fitarg_ne(g)=Fitarg_n(g)+1
+ endif
+ if(g>1 .and. .not.l_hgen) then
+ Fitarg_ne(g)=-1
+ endif
+
+
+ enddo
+
+!-----------------------------------------------------------------------
+!
+! Upsending flags
+!
+
+ mx2=mod(nx,2)
+ my2=mod(my,2)
+
+ if(mx2==1.and.my2==1) then
+ Flsendup_sw(1)=T
+ else &
+ if(mx2==0.and.my2==1) then
+ Flsendup_se(1)=T
+ else &
+ if(mx2==1.and.my2==0) then
+ Flsendup_nw(1)=T
+ else
+ Flsendup_ne(1)=T
+ end if
+
+ nx_up=(nx-1)/2 !+1
+ my_up=(my-1)/2 !+1
+
+
+ Fitarg_up(1)=maxpe_fgen(1)+my_up*ixm(2)+nx_up
+
+
+ if(l_hgen.and.my_hgen < gm) then
+
+ mx2=mod(ix,2)
+ my2=mod(jy,2)
+
+ if(mx2==1.and.my2==1) then
+ Flsendup_sw(2)=T
+ else &
+ if(mx2==0.and.my2==1) then
+ Flsendup_se(2)=T
+ else &
+ if(mx2==1.and.my2==0) then
+ Flsendup_nw(2)=T
+ else
+ Flsendup_ne(2)=T
+ end if
+
+ ix_up=(ix-1)/2 !+1
+ jy_up=(jy-1)/2 !+1
+
+ Fitarg_up(2)=maxpe_fgen(my_hgen)+jy_up*ixm(my_hgen+1)+ix_up
+
+ else
+
+ Flsendup_sw(2)=F
+ Flsendup_se(2)=F
+ Flsendup_nw(2)=F
+ Flsendup_ne(2)=F
+
+ Fitarg_up(2)=-1
+
+ endif
+
+!
+! Downsending flags
+!
+
+ if(my_hgen > 1) then
+
+ ix_dn = 2*ix-1
+ jy_dn = 2*jy-1
+
+ itargdn_sw=maxpe_fgen(my_hgen-2)+(jy_dn-1)*ixm(my_hgen-1)+(ix_dn-1)
+ itargdn_nw=itargdn_sw+ixm(my_hgen-1)
+ itargdn_se=itargdn_sw+1
+ itargdn_ne=itargdn_nw+1
+
+ if(Fimax(my_hgen) <= imL .and. Fleast(2)) then
+ itargdn_se=-1
+ itargdn_ne=-1
+ endif
+ if(Fjmax(my_hgen) <= jmL .and. Flnorth(2)) then
+ itargdn_nw=-1
+ itargdn_ne=-1
+ end if
+
+ else
+
+ itargdn_sw=-1
+ itargdn_se=-1
+ itargdn_nw=-1
+ itargdn_ne=-1
+
+ end if
+!
+! Convert targets in higher generations into real targets
+!
+ call real_itarg(this,Fitarg_w(2))
+ call real_itarg(this,Fitarg_e(2))
+ call real_itarg(this,Fitarg_s(2))
+ call real_itarg(this,Fitarg_n(2))
+
+ call real_itarg(this,Fitarg_sw(2))
+ call real_itarg(this,Fitarg_se(2))
+ call real_itarg(this,Fitarg_nw(2))
+ call real_itarg(this,Fitarg_ne(2))
+
+ if(itargdn_sw .ge. maxpe_fgen(1)) call real_itarg(this,itargdn_sw)
+ if(itargdn_se .ge. maxpe_fgen(1)) call real_itarg(this,itargdn_se)
+ if(itargdn_nw .ge. maxpe_fgen(1)) call real_itarg(this,itargdn_nw)
+ if(itargdn_ne .ge. maxpe_fgen(1)) call real_itarg(this,itargdn_ne)
+
+ call real_itarg(this,Fitarg_up(1))
+ call real_itarg(this,Fitarg_up(2))
+
+!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+! write(200+mype_filt,'(a)')'---------------------------------'
+! write(200+mype_filt,'(a)')'From init_topology_2d'
+! write(200+mype_filt,'(a,2i5)')'mype=',mype
+! write(200+mype_filt,'(a,i5)')'nx=',nx
+! write(200+mype_filt,'(a,i5)')'my=',my
+! write(200+mype_filt,'(a)')'---------------------------------'
+! if(l_hgen ) then
+! write(100+mype_filt,*)' '
+! write(100+mype_filt,'(a,2i5)')'I AM (f),(a):',mype_filt,mype
+! write(100+mype_filt,'(a,i5)') 'mygen= ',mygen
+!
+! write(100+mype_filt,'(a,2i5)')'itarg_w=',itarg_w
+! write(100+mype_filt,'(a,2i5)')'itarg_e=',itarg_e
+! write(100+mype_filt,'(a,2i5)')'itarg_s=',itarg_s
+! write(100+mype_filt,'(a,2i5)')'itarg_n=',itarg_n
+!
+! write(100+mype_filt,'(a,2i5)')'itarg_sw=',itarg_sw
+! write(100+mype_filt,'(a,2i5)')'itarg_se=',itarg_se
+! write(100+mype_filt,'(a,2i5)')'itarg_nw=',itarg_nw
+! write(100+mype_filt,'(a,2i5)')'itarg_ne=',itarg_ne
+! write(100+mype_filt,'(a)')' '
+!
+! if(lsendup_sw) write(100+mype_filt,'(a,l5)')'lsendup_sw=',lsendup_sw
+! if(lsendup_se) write(100+mype_filt,'(a,l5)')'lsendup_se=',lsendup_se
+! if(lsendup_nw) write(100+mype_filt,'(a,l5)')'lsendup_nw=',lsendup_nw
+! if(lsendup_ne) write(100+mype_filt,'(a,l5)')'lsendup_ne=',lsendup_ne
+!
+! write(100+mype_filt,'(a,i5)')'itarg_up=',itarg_up
+!
+! if(lsend_dn) write(100+mype_filt,'(a,l5)')'lsend_dn=',lsend_dn
+!
+! if(my_hgen > 1) then
+! write(100+mype_hgen,'(a,2i5)')'mype_hgen,itargdn_sw=',mype_hgen,itargdn_sw
+! write(100+mype_hgen,'(a,2i5)')'mype_hgen,itargdn_se=',mype_hgen,itargdn_se
+! write(100+mype_hgen,'(a,2i5)')'mype_hgen,itargdn_nw=',mype_hgen,itargdn_nw
+! write(100+mype_hgen,'(a,2i5)')'mype_hgen,itargdn_ne=',mype_hgen,itargdn_ne
+! write(100+mype_hgen,'(a,2i5)')' '
+! if(Flsendup_sw(2)) then
+! write(mype+600,'(a,i4,l2,i4)')'mype_hgen,Flsendup_sw(2),Fitarg_up(2)= ' &
+! ,mype_hgen,Flsendup_sw(2),Fitarg_up(2)
+! endif
+! if(Flsendup_se(2)) then
+! write(mype+600,'(a,i4,l2,i4)')'mype_hgen,Flsendup_se(2),Fitarg_up(2)= ' &
+! ,mype_hgen,Flsendup_se(2),Fitarg_up(2)
+! endif
+! if(Flsendup_nw(2)) then
+! write(mype+600,'(a,i4,l2,i4)')'mype_hgen,Flsendup_nw(2),Fitarg_up(2)= ' &
+! ,mype_hgen,Flsendup_nw(2),Fitarg_up(2)
+! endif
+! if(Flsendup_ne(2)) then
+! write(mype+600,'(a,i4,l2,i4)')'mype_hgen,Flsendup_ne(2),Fitarg_up(2)= ' &
+! ,mype_hgen,Flsendup_ne(2),Fitarg_up(2)
+! endif
+! call finishMPI
+!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+!-----------------------------------------------------------------------
+endsubroutine init_topology_2d
+!----------------------------------------------------------------------
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine real_itarg &
+!***********************************************************************
+! *
+! Definite real targets for high generations *
+! *
+!***********************************************************************
+(this,itarg)
+!-----------------------------------------------------------------------
+implicit none
+class(mg_parameter_type),target::this
+integer(i_kind), intent(inout):: itarg
+include "type_parameter_locpointer.inc"
+include "type_parameter_point2this.inc"
+!-----------------------------------------------------------------------
+if(itarg>-1) then
+ itarg = itarg-nxy(1)
+endif
+!-----------------------------------------------------------------------
+endsubroutine real_itarg
+
+!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+end submodule mg_domain
diff --git a/src/mgbf/mg_domain_loc.f90 b/src/mgbf/mg_domain_loc.f90
new file mode 100644
index 0000000000..183a5f23d7
--- /dev/null
+++ b/src/mgbf/mg_domain_loc.f90
@@ -0,0 +1,796 @@
+submodule(mg_parameter) mg_domain_loc
+!$$$ submodule documentation block
+! . . . .
+! module: mg_domain_loc
+! prgmmr: rancic org: NCEP/EMC date: 2020
+!
+! abstract: Module that defines control paramters for application
+! of MGBF to localization
+!
+! module history log:
+! 2023-04-19 lei - object-oriented coding
+! 2024-01-11 rancic - optimization for ensemble localization
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! init_domain_loc -
+! sidesend_loc -
+! targup_loc -
+! targdn21_loc -
+! targdn32_loc -
+! targdn43_loc -
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use kinds, only: i_kind
+implicit none
+
+!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+contains
+!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine init_domain_loc(this)
+!***********************************************************************
+! !
+! Initialize localization with application of MGBF !
+! !
+!***********************************************************************
+implicit none
+class(mg_parameter_type)::this
+!----------------------------------------------------------------------
+
+call sidesend_loc(this)
+call targup_loc(this)
+call targdn21_loc(this)
+call targdn32_loc(this)
+call targdn43_loc(this)
+
+!----------------------------------------------------------------------
+endsubroutine init_domain_loc
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine sidesend_loc(this)
+!***********************************************************************
+! !
+! Initialize sidesending pararameters for application MGBF to !
+! localization !
+! !
+!***********************************************************************
+implicit none
+class(mg_parameter_type),target::this
+integer(i_kind):: ix_0,jy_0
+integer(i_kind):: ix_c,jy_c
+integer(i_kind):: ix_cc,jy_cc
+integer(i_kind):: ix_ccc,jy_ccc
+include "type_parameter_locpointer.inc"
+include "type_parameter_point2this.inc"
+!-----------------------------------------------------------------------
+
+! write(10,'(a)') ' Generation 2'
+! write(10,'(a)') '----------------------'
+! write(10,'(a)') 'mype Flsouth_loc(1) '
+
+! write(11,'(a)') ' Generation 2'
+! write(11,'(a)') '----------------------'
+! write(11,'(a)') 'mype Flnorth_loc(1) '
+
+! write(12,'(a)') ' Generation 2'
+! write(12,'(a)') '----------------------'
+! write(12,'(a)') 'mype Flwest_loc(1) '
+
+! write(13,'(a)') ' Generation 2'
+! write(13,'(a)') '----------------------'
+! write(13,'(a)') 'mype Fleast_loc(1) '
+
+! write(14,'(a)') ' Generation 2'
+! write(14,'(a)') '----------------------'
+! write(14,'(a)') 'mype Fitarg_s_loc(1) '
+
+! write(15,'(a)') ' Generation 2'
+! write(15,'(a)') '----------------------'
+! write(15,'(a)') 'mype Fitarg_n_loc(1) '
+
+! write(16,'(a)') ' Generation 2'
+! write(16,'(a)') '----------------------'
+! write(16,'(a)') 'mype Fitarg_w_loc(1) '
+
+! write(17,'(a)') ' Generation 2'
+! write(17,'(a)') '----------------------'
+! write(17,'(a)') 'mype Fitarg_e_loc(1) '
+
+! do mype=0,nxm*nym-1
+
+!
+! Generation 1
+!
+ jy_0 = mype/nxm
+ ix_0 = mype - jy_0*nxm +1
+ jy_0 = jy_0 + 1
+
+ Flsouth_loc(1)=jy_0==1
+ Flnorth_loc(1)=jy_0==nym
+ Flwest_loc(1) =ix_0==1
+ Fleast_loc(1) =ix_0==nxm
+
+ if(Flsouth_loc(1)) then
+ Fitarg_s_loc(1) = -1
+ else
+ Fitarg_s_loc(1) = mype-nxm
+ endif
+
+ if(Flnorth_loc(1)) then
+ Fitarg_n_loc(1) = -1
+ else
+ Fitarg_n_loc(1) = mype+nxm
+ endif
+
+ if(Flwest_loc(1)) then
+ Fitarg_w_loc(1) = -1
+ else
+ Fitarg_w_loc(1) = mype-1
+ endif
+
+ if(Fleast_loc(1)) then
+ Fitarg_e_loc(1) = -1
+ else
+ Fitarg_e_loc(1) = mype+1
+ endif
+
+! write(10,'(i5,a,l5)') mype, ' ---> ',Flsouth_loc(1)
+! write(11,'(i5,a,l5)') mype, ' ---> ',Flnorth_loc(1)
+! write(12,'(i5,a,l5)') mype, ' ---> ',Flwest_loc(1)
+! write(13,'(i5,a,l5)') mype, ' ---> ',Fleast_loc(1)
+! write(14,'(i5,a,i5)') mype, ' ---> ',Fitarg_s_loc(1)
+! write(15,'(i5,a,i5)') mype, ' ---> ',Fitarg_n_loc(1)
+! write(16,'(i5,a,i5)') mype, ' ---> ',Fitarg_w_loc(1)
+! write(17,'(i5,a,i5)') mype, ' ---> ',Fitarg_e_loc(1)
+
+!
+! Generation 2
+!
+
+ if(ix_0 <= nxm/2 .and. jy_0 <= nym/2) then
+ ix_c = ix_0
+ jy_c = jy_0
+ else &
+ if( (nxm/2 < ix_0 .and. ix_0 <=nxm) .and. jy_0 <= nym/2) then
+ ix_c = ix_0 - nxm/2
+ jy_c = jy_0
+ else &
+ if(ix_0 <= nxm/2 .and. (nym/2 < jy_0 .and. jy_0 <=nym) ) then
+ ix_c = ix_0
+ jy_c = jy_0 - nym/2
+ else &
+ if( (nxm/2 < ix_0 .and. ix_0 <=nxm) .and. (nym/2 < jy_0 .and. jy_0 <=nym) ) then
+ ix_c = ix_0 - nxm/2
+ jy_c = jy_0 - nym/2
+ end if
+
+ Flsouth_loc(2)=jy_c==1
+ Flnorth_loc(2)=jy_c==nym/2
+ Flwest_loc(2) =ix_c==1
+ Fleast_loc(2) =ix_c==nxm/2
+
+ if(Flsouth_loc(2)) then
+ Fitarg_s_loc(2) = -1
+ else
+ Fitarg_s_loc(2) = mype-nxm
+ endif
+
+ if(Flnorth_loc(2)) then
+ Fitarg_n_loc(2) = -1
+ else
+ Fitarg_n_loc(2) = mype+nxm
+ endif
+
+ if(Flwest_loc(2)) then
+ Fitarg_w_loc(2) = -1
+ else
+ Fitarg_w_loc(2) = mype-1
+ endif
+
+ if(Fleast_loc(2)) then
+ Fitarg_e_loc(2) = -1
+ else
+ Fitarg_e_loc(2) = mype+1
+ endif
+
+! write(10,'(i5,a,l5)') mype, ' ---> ',Flsouth_loc(2)
+! write(11,'(i5,a,l5)') mype, ' ---> ',Flnorth_loc(2)
+! write(12,'(i5,a,l5)') mype, ' ---> ',Flwest_loc(2)
+! write(13,'(i5,a,l5)') mype, ' ---> ',Fleast_loc(2)
+! write(14,'(i5,a,i5)') mype, ' ---> ',Fitarg_s_loc(2)
+! write(15,'(i5,a,i5)') mype, ' ---> ',Fitarg_n_loc(2)
+
+!
+! Generation 3
+!
+ if(ix_c <= nxm/4 .and. jy_c <= nym/4) then
+ ix_cc = ix_c
+ jy_cc = jy_c
+ else &
+ if(ix_c > nxm/4 .and. jy_c <= nym/4) then
+ ix_cc = ix_c-nxm/4
+ jy_cc =jy_c
+ else &
+ if(ix_c <= nxm/4 .and. jy_c > nym/4) then
+ ix_cc = ix_c
+ jy_cc =jy_c-nym/4
+ else &
+ if(ix_c > nxm/4 .and. jy_c > nym/4) then
+ ix_cc = ix_c-nxm/4
+ jy_cc = jy_c-nym/4
+ endif
+
+ Flsouth_loc(3)=jy_cc==1
+ Flnorth_loc(3)=jy_cc==nym/4
+ Flwest_loc(3) =ix_cc==1
+ Fleast_loc(3) =ix_cc==nxm/4
+
+ if(Flsouth_loc(3)) then
+ Fitarg_s_loc(3) = -1
+ else
+ Fitarg_s_loc(3) = mype-nxm
+ endif
+
+ if(Flnorth_loc(3)) then
+ Fitarg_n_loc(3) = -1
+ else
+ Fitarg_n_loc(3) = mype+nxm
+ endif
+
+ if(Flwest_loc(3)) then
+ Fitarg_w_loc(3) = -1
+ else
+ Fitarg_w_loc(3) = mype-1
+ endif
+
+ if(Fleast_loc(3)) then
+ Fitarg_e_loc(3) = -1
+ else
+ Fitarg_e_loc(3) = mype+1
+ endif
+
+! write(10,'(i5,a,l5)') mype, ' ---> ',Flsouth_loc(3)
+! write(11,'(i5,a,l5)') mype, ' ---> ',Flnorth_loc(3)
+! write(12,'(i5,a,l5)') mype, ' ---> ',Flwest_loc(3)
+! write(13,'(i5,a,l5)') mype, ' ---> ',Fleast_loc(3)
+! write(14,'(i5,a,i5)') mype, ' ---> ',Fitarg_s_loc(3)
+! write(15,'(i5,a,i5)') mype, ' ---> ',Fitarg_n_loc(3)
+
+!
+! Generation 4
+!
+ if(ix_cc <= nxm/8 .and. jy_cc <= nym/8) then
+ ix_ccc = ix_cc; jy_ccc = jy_cc
+ else &
+ if(ix_cc > nxm/8 .and. jy_cc <= nym/8) then
+ ix_ccc = ix_cc-nxm/8; jy_ccc =jy_cc
+ else &
+ if(ix_cc <= nxm/8 .and. jy_cc > nym/8) then
+ ix_ccc = ix_cc; jy_ccc =jy_cc-nym/8
+ else &
+ if(ix_cc > nxm/8 .and. jy_cc > nym/8) then
+ ix_ccc = ix_cc-nxm/8; jy_ccc =jy_cc-nym/8
+ endif
+
+ Flsouth_loc(4)=jy_ccc==1
+ Flnorth_loc(4)=jy_ccc==nym/8
+ Flwest_loc(4) =ix_ccc==1
+ Fleast_loc(4) =ix_ccc==nxm/8
+
+ if(Flsouth_loc(4)) then
+ Fitarg_s_loc(4) = -1
+ else
+ Fitarg_s_loc(4) = mype-nxm
+ endif
+
+ if(Flnorth_loc(4)) then
+ Fitarg_n_loc(4) = -1
+ else
+ Fitarg_n_loc(4) = mype+nxm
+ endif
+
+ if(Flwest_loc(4)) then
+ Fitarg_w_loc(4) = -1
+ else
+ Fitarg_w_loc(4) = mype-1
+ endif
+
+ if(Fleast_loc(4)) then
+ Fitarg_e_loc(4) = -1
+ else
+ Fitarg_e_loc(4) = mype+1
+ endif
+
+! enddo
+
+!----------------------------------------------------------------------
+endsubroutine sidesend_loc
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine targup_loc(this)
+!***********************************************************************
+! !
+! Initialize upsending pararameters for application MGBF to !
+! localization !
+! !
+!***********************************************************************
+implicit none
+class(mg_parameter_type),target::this
+integer(i_kind):: ix_0,jy_0
+integer(i_kind):: ix_c,jy_c,mype_c
+integer(i_kind):: ix_prox,jy_prox,targup
+integer(i_kind):: n,is,js, mj2, il,jl
+include "type_parameter_locpointer.inc"
+include "type_parameter_point2this.inc"
+!--------------------------------------------------------------------
+
+!do mype=0,nxm*nym-1
+
+ jy_0 = mype/nxm+1
+ ix_0 = mype-(jy_0-1)*nxm+1
+
+ mj2=mod(jy_0,2)
+ mype_c=(nxm/2)*(jy_0-2+mj2)/2+(ix_0-1)/2
+
+ jy_c = mype_c/(nxm/2)+1
+ ix_c = mype_c-(jy_c-1)*(nxm/2)+1
+
+ lsendup_sw_loc=(mod(ix_0,2)==1).and.(mod(jy_0,2)==1)
+ lsendup_se_loc=(mod(ix_0,2)==0).and.(mod(jy_0,2)==1)
+ lsendup_nw_loc=(mod(ix_0,2)==1).and.(mod(jy_0,2)==0)
+ lsendup_ne_loc=(mod(ix_0,2)==0).and.(mod(jy_0,2)==0)
+
+!
+! g1 --> g2
+!
+
+ do n=1,4
+ js=(n-1)/2
+ is= n-1 -js*2
+ ix_prox=ix_c+is*nxm/2
+ jy_prox=jy_c+js*nym/2
+
+ Fitargup_loc12(n)=nxm*(jy_prox-1)+ix_prox-1
+ enddo
+
+! write(12,'(i5,a,4i5)') mype,' ---> ', Fitargup_loc12(1),Fitargup_loc12(2),Fitargup_loc12(3),Fitargup_loc12(4)
+
+!
+! g2 --> g3
+!
+ il = (ix_0-1)/(nxm/2)
+ jl = (jy_0-1)/(nym/2)
+
+ do n=1,4
+ js=(n-1)/2
+ is= n-1-js*2
+ ix_prox=ix_c +is*nxm/4 + il*nxm/4
+ jy_prox=jy_c +js*nym/4 + jl*nym/4
+
+ Fitargup_loc23(n)=nxm*(jy_prox-1)+ix_prox-1
+ enddo
+
+! write(23,'(i5,a,4i5)') mype,' ---> ', Fitargup_loc23(1),Fitargup_loc23(2),Fitargup_loc23(3),Fitargup_loc23(4)
+
+!
+! g3 --> g4
+!
+ il = (ix_0-1)/(nxm/4)
+ jl = (jy_0-1)/(nym/4)
+
+ do n=1,4
+ js=(n-1)/2
+ is= n-1-js*2
+ ix_prox=ix_c +is*nxm/8 + il*nxm/8
+ jy_prox=jy_c +js*nym/8 + jl*nym/8
+
+ Fitargup_loc34(n)=nxm*(jy_prox-1)+ix_prox-1
+ enddo
+
+! write(34,'(i5,a,4i5)') mype,' ---> ',
+!Fitargup_loc34(1),Fitargup_loc34(2),Fitargup_loc34(3),Fitargup_loc34(4)
+
+!enddo
+
+!----------------------------------------------------------------------
+endsubroutine targup_loc
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine targdn21_loc(this)
+!***********************************************************************
+! !
+! Initialize downsending pararameters for application MGBF to !
+! localization from g2 go g1 !
+! !
+!***********************************************************************
+implicit none
+class(mg_parameter_type),target::this
+integer:: ix_t,jy_t
+integer:: ix_l,jy_l
+integer:: ix_sw,jy_sw
+integer:: ix_se,jy_se
+integer:: ix_nw,jy_nw
+integer:: ix_ne,jy_ne
+include "type_parameter_locpointer.inc"
+include "type_parameter_point2this.inc"
+!------------------------------------------------------------------------
+
+! write(11,'(a)') 'mype itargdn_xx_loc21 nsq21 '
+! write(11,'(a)') '---------------------------------'
+
+! do mype=0,nxm*nym-1
+
+ jy_t = mype/nxm+1
+ ix_t = mype-(jy_t-1)*nxm+1
+
+!
+! Square 1
+!
+ if(ix_t <= nxm/2 .and. jy_t <= nym/2) then
+ ix_l = ix_t
+ jy_l = jy_t
+ nsq21 = 1
+ else &
+!
+! Square 2
+!
+ if( (nxm/2 < ix_t .and. ix_t <= nxm) .and. jy_t <= nym/2) then
+ ix_l = ix_t-nxm/2
+ jy_l = jy_t
+ nsq21 = 2
+ else &
+!
+! Square 3
+!
+ if( ix_t <= nxm/2 .and. (nym/2 < jy_t .and. jy_t <= nym)) then
+ ix_l = ix_t
+ jy_l = jy_t-nym/2
+ nsq21 = 3
+ else &
+!
+! Square 4
+!
+ if( (nxm/2 < ix_t .and. ix_t <= nxm) .and. (nym/2 < jy_t .and. jy_t <= nym)) then
+ ix_l = ix_t-nxm/2
+ jy_l = jy_t-nym/2
+ nsq21 = 4
+ endif
+
+ ix_sw = 2*ix_l-1
+ jy_sw = 2*jy_l-1
+ itargdn_sw_loc21 = nxm*(jy_sw-1)+ix_sw-1
+
+ ix_se = ix_sw+1
+ jy_se = jy_sw
+ itargdn_se_loc21 = nxm*(jy_se-1)+ix_se-1
+
+ ix_nw = ix_sw
+ jy_nw = jy_sw+1
+ itargdn_nw_loc21 = nxm*(jy_nw-1)+ix_nw-1
+
+ ix_ne = ix_nw+1
+ jy_ne = jy_nw
+ itargdn_ne_loc21 = nxm*(jy_ne-1)+ix_ne-1
+
+! write(11,'(i6,a,2i4)') mype,' <-- itargdn_sw_loc21 ',itargdn_sw_loc21,nsq
+! write(11,'(i6,a,2i4)') mype,' <-- itargdn_se_loc21 ',itargdn_se_loc21,nsq
+! write(11,'(i6,a,2i4)') mype,' <-- itargdn_nw_loc21 ',itargdn_nw_loc21,nsq
+! write(11,'(i6,a,2i4)') mype,' <-- itargdn_ne_loc21 ',itargdn_ne_loc21,nsq
+
+! end do
+!-----------------------------------------------------------
+endsubroutine targdn21_loc
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine targdn32_loc(this)
+!***********************************************************************
+! !
+! Initialize downsending pararameters for application MGBF to !
+! localization from g3 go g2 !
+! !
+!***********************************************************************
+implicit none
+class(mg_parameter_type),target::this
+integer(i_kind):: ix_t,jy_t
+integer(i_kind):: ix_l,jy_l
+integer(i_kind):: ix_sw,jy_sw
+integer(i_kind):: ix_se,jy_se
+integer(i_kind):: ix_nw,jy_nw
+integer(i_kind):: ix_ne,jy_ne
+integer(i_kind):: facx,facy
+include "type_parameter_locpointer.inc"
+include "type_parameter_point2this.inc"
+!-----------------------------------------------------------
+
+! write(32,'(a)') 'mype itargdn_xx_loc32 nsq32 '
+! write(32,'(a)') '---------------------------------'
+
+! do mype=0,nxm*nym-1
+
+ jy_t = mype/nxm+1
+ ix_t = mype-(jy_t-1)*nxm+1
+
+!
+! Square 1
+!
+ if(ix_t <= nxm/4 .and. jy_t <= nym/4) then
+ ix_l = ix_t
+ jy_l = jy_t
+ nsq32 = 1
+ facx = 0
+ facy = 0
+ else &
+!
+! Square 2
+!
+ if( (nxm/4 < ix_t .and.ix_t<=nxm/2 ) .and. jy_t <= nym/4) then
+ ix_l = ix_t-nxm/4
+ jy_l = jy_t
+ nsq32 = 2
+ facx = 0
+ facy = 0
+ else &
+!
+! Square 3
+!
+ if( ix_t <= nxm/4 .and. (nym/4 < jy_t .and. jy_t <= nym/2)) then
+ ix_l = ix_t
+ jy_l = jy_t-nym/4
+ nsq32 = 3
+ facx = 0
+ facy = 0
+ else &
+!
+! Square 4
+!
+ if( (nxm/4 < ix_t .and. ix_t <= nxm/2) .and. (nym/4 < jy_t .and. jy_t <= nym/2)) then
+ ix_l = ix_t-nxm/4
+ jy_l = jy_t-nym/4
+ nsq32 = 4
+ facx = 0
+ facy = 0
+ else &
+!
+! Square 5
+!
+ if( (nxm/2 1) call this%init_mg_MPI
+
+!***
+!*** Initialize integration domain
+!***
+call this%init_mg_domain
+if(this%l_loc) then
+ call this%init_domain_loc
+endif
+
+!---------------------------------------------------------------------------
+!
+! All others are function of km2,km3,km,nm,mm,im,jm
+! and needs to be called separately for each application
+!
+!---------------------------------------------------------------------------
+!***
+!*** Define km and WORKA array based on input from mg_parameters and
+!*** depending on specific application
+!***
+
+!***
+!*** Allocate variables, define weights, prepare mapping
+!*** between analysis and filter grid
+!***
+
+call this%allocate_mg_intstate
+
+call this%def_offset_coef
+
+call this%def_mg_weights
+
+if(this%mgbf_line) then
+ call this%init_mg_line
+endif
+
+call this%lsqr_mg_coef
+
+call this%lwq_vertical_coef(this%lm_a,this%lm,this%cvf1,this%cvf2,this%cvf3,this%cvf4,this%lref)
+
+!***
+!*** Just for testing of standalone version. In GSI WORKA will be given
+!*** through a separate subroutine
+!***
+
+!call input_3d(WORKA( 1: lm,:,:),1,1, 1,mm,nm, lm,mm0,4,3)
+!call input_3d(WORKA( lm+1:2*lm,:,:),1,1, lm+1,mm,nm,2*lm,mm0,6,5)
+!call input_3d(WORKA(2*lm+1:3*lm,:,:),1,1,2*lm+1,mm,nm,3*lm,mm0,2,1)
+!call input_3d(WORKA(3*lm+1:4*lm,:,:),1,1,3*lm+1,mm,nm,4*lm,mm0,3,2)
+!call input_3d(WORKA(4*lm+1:5*lm,:,:),1,1,4*lm+1,mm,nm,5*lm,mm0,7,3)
+!call input_3d(WORKA(5*lm+1:6*lm,:,:),1,1,5*lm+1,mm,nm,6*lm,mm0,4,5)
+
+!call input_3d(WORKA(6*lm+1:6*lm+1,:,:),1,1,6*lm+1,mm,nm,6*lm+1,mm0,2,1)
+!call input_3d(WORKA(6*lm+2:6*lm+2,:,:),1,1,6*lm+2,mm,nm,6*lm+2,mm0,4,1)
+!call input_3d(WORKA(6*lm+3:6*lm+3,:,:),1,1,6*lm+3,mm,nm,6*lm+3,mm0,5,1)
+!call input_3d(WORKA(6*lm+4:6*lm+4,:,:),1,1,6*lm+4,mm,nm,6*lm+4,mm0,7,1)
+
+!-----------------------------------------------------------------------
+endsubroutine mg_initialize
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine mg_finalize(this)
+!**********************************************************************!
+! !
+! Finalize multigrid Beta Function !
+! M. Rancic (2020) !
+!***********************************************************************
+implicit none
+class (mg_intstate_type)::this
+
+real(r_kind), allocatable, dimension(:,:):: PA, VA
+integer(i_kind):: n,m,L
+integer:: nm,mm,lm
+!-----------------------------------------------------------------------
+
+if(this%ldelta) then
+ !
+ ! Horizontal cross-section
+ !
+ nm=this%nm
+ mm=this%mm
+ lm=this%lm
+endif
+
+if(this%nxm*this%nym>1) call this%barrierMPI
+
+call this%deallocate_mg_intstate
+
+!-----------------------------------------------------------------------
+endsubroutine mg_finalize
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+end submodule mg_entrymod
diff --git a/src/mgbf/mg_filtering.f90 b/src/mgbf/mg_filtering.f90
new file mode 100644
index 0000000000..714a4b6bf4
--- /dev/null
+++ b/src/mgbf/mg_filtering.f90
@@ -0,0 +1,1629 @@
+submodule(mg_intstate) mg_filtering
+!$$$ submodule documentation block
+! . . . .
+! module: mg_filtering
+! prgmmr: rancic org: NCEP/EMC date: 2020
+!
+! abstract: Contains all multigrid filtering prodecures
+!
+! module history log:
+! 2023-04-19 lei - object-oriented coding
+! 2024-01-11 rancic - optimization for ensemble localization
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! filtering_procedure -
+! filtering_rad3 -
+! filtering_lin3 -
+! filtering_rad2_bkg -
+! filtering_lin2_bkg -
+! filtering_fast_bkg -
+! filtering_rad2_ens -
+! filtering_lin2_ens -
+! filtering_fast_ens -
+! filtering_rad_highest -
+! sup_vrbeta1 -
+! sup_vrbeta1T -
+! sup_vrbeta3 -
+! sup_vrbeta3T -
+! sup_vrbeta1_ens -
+! sup_vrbeta1T_ens -
+! sup_vrbeta1_bkg -
+! sup_vrbeta1T_bkg -
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mg_timers
+use kinds, only: r_kind,i_kind
+use jp_pbfil3, only: dibetat,dibeta
+use mpi
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+contains
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filtering_procedure(this,mg_filt,mg_filt_flag)
+!***********************************************************************
+! !
+! Driver for Multigrid filtering procedures with Helmholtz operator !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: mg_filt
+integer(i_kind),intent(in):: mg_filt_flag
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+if(this%nxm*this%nym>1) then
+ select case(mg_filt)
+ case(1)
+ call this%filtering_rad3
+ case(2)
+ call this%filtering_lin3
+ case(3)
+ call this%filtering_rad2_bkg
+ case(4)
+ call this%filtering_lin2_bkg
+ case(5)
+ call this%filtering_fast_bkg
+ case(6)
+ call this%filtering_rad2_ens(mg_filt_flag)
+ case(7)
+ call this%filtering_lin2_ens(mg_filt_flag)
+ case(8)
+ call this%filtering_fast_ens(mg_filt_flag)
+ end select
+else
+ call this%filtering_rad_highest
+endif
+!-----------------------------------------------------------------------
+endsubroutine filtering_procedure
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filtering_rad3(this)
+!***********************************************************************
+! !
+! Multigrid filtering procedure: !
+! !
+! - Multiple of 2D and 3D variables !
+! - 1 upsending and downsending !
+! - Applicaton of Helmholtz differential operator !
+! - 3d radial filter !
+! !
+!***********************************************************************
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target::this
+real(r_kind), allocatable, dimension(:,:,:):: VM2D
+real(r_kind), allocatable, dimension(:,:,:):: HM2D
+real(r_kind), allocatable, dimension(:,:,:,:):: VM3D
+real(r_kind), allocatable, dimension(:,:,:,:):: HM3D
+integer(i_kind) L,i,j
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+allocate(VM3D(km3,1-hx:im+hx,1-hy:jm+hy,lm)) ; VM3D=0.
+allocate(VM2D(km2,1-hx:im+hx,1-hy:jm+hy )) ; VM2D=0.
+allocate(HM3D(km3,1-hx:im+hx,1-hy:jm+hy,lm)) ; HM3D=0.
+allocate(HM2D(km2,1-hx:im+hx,1-hy:jm+hy )) ; HM2D=0.
+
+!***
+!*** Adjoint interpolate and upsend
+!***
+ call btim(upsend_tim)
+ call this%upsending_all(VALL,HALL,lquart)
+ call etim(upsend_tim)
+!***
+!*** Apply adjoint of Beta filter at all generations
+!***
+ call btim(hfiltT_tim)
+ call this%stack_to_composite(VALL,VM2D,VM3D)
+ call this%rbetaT(km2,hx,1,im,hy,1,jm,pasp2,ss2,VM2D)
+ call this%sup_vrbeta3T(km3,hx,hy,hz,im,jm,lm,pasp3,ss3,VM3D)
+ call this%composite_to_stack(VM2D,VM3D,VALL)
+
+ if(l_hgen) then
+ call this%stack_to_composite(HALL,HM2D,HM3D)
+ call this%rbetaT(km2,hx,1,im,hy,1,jm,pasp2,ss2,HM2D)
+ call this%sup_vrbeta3T(km3,hx,hy,hz,im,jm,lm,pasp3,ss3,HM3D)
+ call this%composite_to_stack(HM2D,HM3D,HALL)
+ endif
+ call etim(hfiltT_tim)
+
+ call btim(bocoT_tim)
+ call this%bocoT_2d(VALL,km,im,jm,hx,hy)
+ call this%bocoT_2d(HALL,km,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(bocoT_tim)
+!***
+!*** Apply (a-b\nabla^2)
+!***
+ call btim(weight_tim)
+ call this%weighting_all(VALL,HALL,lhelm)
+ call etim(weight_tim)
+!***
+!*** Apply Beta filter at all generations
+!***
+ call btim(boco_tim)
+ call this%boco_2d(VALL,km,im,jm,hx,hy)
+ call this%boco_2d(HALL,km,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(boco_tim)
+
+ call btim(hfilt_tim)
+ call this%stack_to_composite(VALL,VM2D,VM3D)
+ call this%rbeta(km2,hx,1,im,hy,1,jm,pasp2,ss2,VM2D(:,:,:))
+ call this%sup_vrbeta3(km3,hx,hy,hz,im,jm,lm,pasp3,ss3,VM3D)
+ call this%composite_to_stack(VM2D,VM3D,VALL)
+ if(l_hgen) then
+ call this%stack_to_composite(HALL,HM2D,HM3D)
+ call this%rbeta(km2,hx,1,im,hy,1,jm,pasp2,ss2,HM2D(:,:,:))
+ call this%sup_vrbeta3(km3,hx,hy,hz,im,jm,lm,pasp3,ss3,HM3D)
+ call this%composite_to_stack(HM2D,HM3D,HALL)
+ endif
+ call etim(hfilt_tim)
+!***
+!*** Downsend, interpolate and add
+!*** Then zero high generations
+!***
+ call btim(dnsend_tim)
+ call this%downsending_all(HALL,VALL,lquart)
+ call etim(dnsend_tim)
+
+deallocate(VM3D)
+deallocate(VM2D)
+deallocate(HM3D)
+deallocate(HM2D)
+!-----------------------------------------------------------------------
+endsubroutine filtering_rad3
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filtering_lin3(this)
+!***********************************************************************
+! !
+! Multigrid filtering procedure: !
+! !
+! - Multiple of 2D line filter !
+! - 1 upsending and downsending !
+! - Applicaton of Helmholtz differential operator !
+! - 3d line filter !
+! !
+!***********************************************************************
+!TEST
+use, intrinsic :: ieee_arithmetic
+!TEST
+use jp_pkind2, only: fpi
+implicit none
+class (mg_intstate_type),target::this
+integer(i_kind) k,i,j,L
+integer(i_kind) icol,iout,jout,lout
+logical:: ff
+real(r_kind), allocatable, dimension(:,:,:):: VM2D
+real(r_kind), allocatable, dimension(:,:,:):: HM2D
+real(r_kind), allocatable, dimension(:,:,:,:):: VM3D
+real(r_kind), allocatable, dimension(:,:,:,:):: HM3D
+real(r_kind), allocatable, dimension(:,:,:,:):: W
+real(r_kind), allocatable, dimension(:,:,:,:):: H
+integer(fpi), allocatable, dimension(:,:,:):: JCOL
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+allocate(VM3D(km3,1-hx:im+hx,1-hy:jm+hy,lm)) ; VM3D=0.
+allocate(VM2D(km2,1-hx:im+hx,1-hy:jm+hy )) ; VM2D=0.
+allocate(HM3D(km3,1-hx:im+hx,1-hy:jm+hy,lm)) ; HM3D=0.
+allocate(HM2D(km2,1-hx:im+hx,1-hy:jm+hy )) ; HM2D=0.
+allocate(W(km3,1-hx:im+hx,1-hy:jm+hy,1-hz:lm+hz)) ; W=0.
+allocate(H(km3,1-hx:im+hx,1-hy:jm+hy,1-hz:lm+hz)) ; H=0.
+allocate(JCOL(1:im,1:jm,1:Lm)) ; JCOL=0
+
+!***
+!*** Adjoint interpolate and upsend
+!***
+ call btim(upsend_tim)
+ call this%upsending_all(VALL,HALL,lquart)
+ call etim(upsend_tim)
+!***
+!*** Apply adjoint of Beta filter at all generations
+!***
+
+!
+! From single stack to composite variables
+!
+ call btim(hfiltT_tim)
+ call this%stack_to_composite(VALL,VM2D,VM3D)
+ if(l_hgen) then
+ call this%stack_to_composite(HALL,HM2D,HM3D)
+ endif
+ call etim(hfiltT_tim)
+!
+! Apply adjoint filter to 2D variables first
+!
+ do icol=3,1,-1
+ call btim(hfiltT_tim)
+ call dibetat(km2,1-hx,1,im,im+hx, 1-hy,1,jm,jm+hy, nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol), VM2D, ff, iout,jout)
+ call etim(hfiltT_tim)
+ call btim(bocoT_tim)
+ call this%bocoT_2d(VM2D,km2,im,jm,hx,hy)
+ call etim(bocoT_tim)
+ enddo
+
+ do icol=3,1,-1
+ if(l_hgen) then
+ call btim(hfiltT_tim)
+ call dibetat(km2,1-hx,1,im,im+hx, 1-hy,1,jm,jm+hy, nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol), HM2D, ff, iout,jout)
+ call etim(hfiltT_tim)
+ endif
+ call btim(bocoT_tim)
+ call this%bocoT_2d(HM2D,km2,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(bocoT_tim)
+ enddo
+!
+! Create and apply adjoint filter to extended 3D variables
+!
+ W(:,:,:,1:lm)=VM3D(:,:,:,1:lm)
+ do icol=7,1,-1
+ call btim(hfiltT_tim)
+ do L=1,hz
+ W(:,:,:,1-L )=W(:,:,:,1+L )
+ W(:,:,:,LM+L)=W(:,:,:,LM-L)
+ enddo
+ call dibetat(km3,1-hx,1,im,im+hx, 1-hy,1,jm,jm+hy, 1-hz,1,lm,lm+hz,icol, nfil &
+ ,qcols,dixs3,diys3,dizs3,JCOL,vpasp3, W, ff, iout,jout,lout)
+ call etim(hfiltT_tim)
+ call btim(bocoT_tim)
+ call this%bocoT_3d(W,km3,im,jm,Lm,hx,hy,hz,Fimax,Fjmax)
+ call etim(bocoT_tim)
+ enddo
+
+ if(l_hgen) then
+ H(:,:,:,1:lm)=HM3D(:,:,:,1:lm)
+ endif
+ do icol=7,1,-1
+ if(l_hgen) then
+ call btim(hfiltT_tim)
+ do L=1,hz
+ H(:,:,:,1-L )=H(:,:,:,1+L )
+ H(:,:,:,LM+L)=H(:,:,:,LM-L)
+ end do
+ call dibetat(km3,1-hx,1,im,im+hx, 1-hy,1,jm,jm+hy, 1-hz,1,lm,lm+hz,icol, nfil &
+ ,qcols,dixs3,diys3,dizs3,JCOL,vpasp3, H, ff, iout,jout,lout)
+ call etim(hfiltT_tim)
+ endif
+ call btim(bocoT_tim)
+ call this%bocoT_3d(H,km3,im,jm,Lm,hx,hy,hz,Fimax,Fjmax,2,gm)
+ call etim(bocoT_tim)
+ enddo
+!
+! Go back from extended 3D variables and combine them with 2D variables in one stacked variable
+!
+ call btim(hfiltT_tim)
+ VM3D(:,:,:,1:lm)=W(:,:,:,1:lm)
+ call this%composite_to_stack(VM2D,VM3D,VALL)
+ if(l_hgen) then
+ HM3D(:,:,:,1:lm)=H(:,:,:,1:lm)
+ call this%composite_to_stack(HM2D,HM3D,HALL)
+ endif
+ call etim(hfiltT_tim)
+!***
+!*** Apply (a-b\nabla^2)
+!***
+ call btim(weight_tim)
+ call this%weighting_all(VALL,HALL,lhelm)
+ call etim(weight_tim)
+!***
+!*** Apply Beta filter at all generations
+!***
+
+!
+! From single stacked to composite variables
+!
+ call btim(hfilt_tim)
+ call this%stack_to_composite(VALL,VM2D,VM3D)
+ if(l_hgen) then
+ call this%stack_to_composite(HALL,HM2D,HM3D)
+ endif
+ call etim(hfilt_tim)
+!
+! Apply filter to 2D variables first
+!
+ do icol=1,3
+ call btim(boco_tim)
+ call this%boco_2d(VM2D,km2,im,jm,hx,hy)
+ call etim(boco_tim)
+ call btim(hfilt_tim)
+ call dibeta(km2,1-hx,1,im,im+hx, 1-hy,1,jm,jm+hy, nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol), VM2D, ff, iout,jout)
+ call etim(hfilt_tim)
+ enddo
+
+ do icol=1,3
+ call btim(boco_tim)
+ call this%boco_2d(HM2D,km2,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(boco_tim)
+ if(l_hgen) then
+ call btim(hfilt_tim)
+ call dibeta(km2,1-hx,1,im,im+hx, 1-hy,1,jm,jm+hy, nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol), HM2D, ff, iout,jout)
+ call etim(hfilt_tim)
+ endif
+ enddo
+!
+! Create and apply filter to extended 3D variables
+!
+ W(:,:,:,1:lm)=VM3D(:,:,:,1:lm)
+ do L=1,hz
+ do j=1-hy,jm+hy
+ do i=1-hx,im+hx
+ W(:,i,j,1-L )=W(:,i,j,1+L )
+ W(:,i,j,LM+L)=W(:,i,j,LM-L)
+ enddo
+ enddo
+ enddo
+
+ do icol=1,7
+ call btim(boco_tim)
+ call this%boco_3d(W,km3,im,jm,lm,hx,hy,hz,Fimax,Fjmax)
+ call etim(boco_tim)
+ call btim(hfilt_tim)
+ call dibeta(km3,1-hx,1,im,im+hx, 1-hy,1,jm,jm+hy, 1-hz,1,lm,lm+hz,icol, nfil &
+ ,qcols,dixs3,diys3,dizs3,JCOL,vpasp3, W, ff, iout,jout,lout)
+ call etim(hfilt_tim)
+ enddo
+
+ if(l_hgen) then
+ H(:,:,:,1:lm)=HM3D(:,:,:,1:lm)
+ do L=1,hz
+ do j=1-hy,jm+hy
+ do i=1-hx,im+hx
+ H(:,i,j,1-L )=H(:,i,j,1+L )
+ H(:,i,j,LM+L)=H(:,i,j,LM-L)
+ enddo
+ enddo
+ enddo
+ endif
+ do icol=1,7
+ call btim(boco_tim)
+ call this%boco_3d(H,km3,im,jm,lm,hx,hy,hz,Fimax,Fjmax,2,gm)
+ call etim(boco_tim)
+ if(l_hgen) then
+ call btim(hfilt_tim)
+ call dibeta(km3,1-hx,1,im,im+hx, 1-hy,1,jm,jm+hy, 1-hz,1,lm,lm+hz,icol, nfil &
+ ,qcols,dixs3,diys3,dizs3,JCOL,vpasp3, H, ff, iout,jout,lout)
+ call etim(hfilt_tim)
+ endif
+ enddo
+!
+! Go back from extended 3D variables and combine them with 2D variables in one stacked variable
+!
+ call btim(hfilt_tim)
+ VM3D(:,:,:,1:lm)=W(:,:,:,1:lm)
+ call this%composite_to_stack(VM2D,VM3D,VALL)
+ if(l_hgen) then
+ HM3D(:,:,:,1:lm)=H(:,:,:,1:lm)
+ call this%composite_to_stack(HM2D,HM3D,HALL)
+ endif
+ call etim(hfilt_tim)
+!***
+!*** Downsend, interpolate and add, then zero high generations
+!***
+ call btim(dnsend_tim)
+ call this%downsending_all(HALL,VALL,lquart)
+ call etim(dnsend_tim)
+
+deallocate(VM3D)
+deallocate(VM2D)
+deallocate(HM3D)
+deallocate(HM2D)
+deallocate(W)
+deallocate(H)
+deallocate(JCOL)
+!-----------------------------------------------------------------------
+endsubroutine filtering_lin3
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filtering_rad2_bkg(this)
+!***********************************************************************
+! !
+! Multigrid filtering procedure: !
+! !
+! - Apply vertical filter before and after horizontal !
+! - 2d radial filter !
+! !
+!***********************************************************************
+implicit none
+class (mg_intstate_type),target::this
+integer(i_kind) L,i,j
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!***
+!*** Adjoint of beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfiltT_tim)
+ call this%sup_vrbeta1T_bkg(km,km3,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfiltT_tim)
+ endif
+!***
+!*** Adjoint interpolate and upsend
+!***
+ call btim(upsend_tim)
+ call this%upsending_all(VALL,HALL,lquart)
+ call etim(upsend_tim)
+!***
+!*** Apply adjoint of Beta filter at all generations
+!***
+ call btim(hfiltT_tim)
+ call this%rbetaT(km,hx,1,im,hy,1,jm,pasp2,ss2,VALL(:,:,:))
+ if(l_hgen) then
+ call this%rbetaT(km,hx,1,im,hy,1,jm,pasp2,ss2,HALL(:,:,:))
+ endif
+ call etim(hfiltT_tim)
+
+ call btim(bocoT_tim)
+ call this%bocoT_2d(VALL,km,im,jm,hx,hy)
+ call this%bocoT_2d(HALL,km,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(bocoT_tim)
+!***
+!*** Apply (a-b\nabla^2)
+!***
+ call btim(weight_tim)
+ call this%weighting_all(VALL,HALL,lhelm)
+ call etim(weight_tim)
+!***
+!*** Apply Beta filter at all generations
+!***
+ call btim(boco_tim)
+ call this%boco_2d(VALL,km,im,jm,hx,hy)
+ call this%boco_2d(HALL,km,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(boco_tim)
+
+ call btim(hfilt_tim)
+ call this%rbeta(km,hx,1,im,hy,1,jm,pasp2,ss2,VALL(:,:,:))
+ if(l_hgen) then
+ call this%rbeta(km,hx,1,im,hy,1,jm,pasp2,ss2,HALL(:,:,:))
+ endif
+ call etim(hfilt_tim)
+!***
+!*** Downsend, interpolate and add, then zero high generations
+!***
+ call btim(dnsend_tim)
+ call this%downsending_all(HALL,VALL,lquart)
+ call etim(dnsend_tim)
+!***
+!*** Apply beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfilt_tim)
+ call this%sup_vrbeta1_bkg(km,km3,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfilt_tim)
+ endif
+!-----------------------------------------------------------------------
+endsubroutine filtering_rad2_bkg
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filtering_lin2_bkg(this)
+!***********************************************************************
+! !
+! Multigrid filtering procedure: !
+! !
+! - Apply vertical filter before and after horizontal !
+! - 2d line filter !
+! !
+!***********************************************************************
+implicit none
+class (mg_intstate_type),target::this
+integer(i_kind) L,i,j
+integer(i_kind) icol,iout,jout
+logical:: ff
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+!***
+!*** Adjoint of beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfiltT_tim)
+ call this%sup_vrbeta1T_bkg(km,km3,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfiltT_tim)
+ endif
+!***
+!*** Adjoint interpolate and upsend
+!***
+
+ call btim(upsend_tim)
+ call this%upsending_all(VALL,HALL,lquart)
+ call etim(upsend_tim)
+!***
+!*** Apply adjoint of Beta filter at all generations
+!***
+ do icol=3,1,-1
+ call btim(hfiltT_tim)
+ call dibetat(km,1-hx,1,im,im+hx,1-hy,1,jm,jm+hy,nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol),VALL,ff,iout,jout)
+ call etim(hfiltT_tim)
+ call btim(bocoT_tim)
+ call this%bocoT_2d(VALL,km,im,jm,hx,hy)
+ call etim(bocoT_tim)
+ enddo
+
+ do icol=3,1,-1
+ if(l_hgen) then
+ call btim(hfiltT_tim)
+ call dibetat(km,1-hx,1,im,im+hx,1-hy,1,jm,jm+hy,nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol),HALL,ff,iout,jout)
+ call etim(hfiltT_tim)
+ endif
+ call btim(bocoT_tim)
+ call this%bocoT_2d(HALL,km,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(bocoT_tim)
+ enddo
+!***
+!*** Apply (a-b\nabla^2)
+!***
+ call btim(weight_tim)
+ call this%weighting_all(VALL,HALL,lhelm)
+ call etim(weight_tim)
+!***
+!*** Apply Beta filter at all generations
+!***
+ do icol=1,3
+ call btim(boco_tim)
+ call this%boco_2d(VALL,km,im,jm,hx,hy)
+ call etim(boco_tim)
+ call btim(hfilt_tim)
+ call dibeta(km,1-hx,1,im,im+hx,1-hy,1,jm,jm+hy,nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol),VALL,ff,iout,jout)
+ call etim(hfilt_tim)
+ enddo
+
+ do icol=1,3
+ call btim(boco_tim)
+ call this%boco_2d(HALL,km,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(boco_tim)
+ if(l_hgen) then
+ call btim(hfilt_tim)
+ call dibeta(km,1-hx,1,im,im+hx,1-hy,1,jm,jm+hy,nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol),HALL,ff,iout,jout)
+ call etim(hfilt_tim)
+ endif
+ enddo
+!***
+!*** Downsend, interpolate and add, then zero high generations
+!***
+ call btim(dnsend_tim)
+ call this%downsending_all(HALL,VALL,lquart)
+ call etim(dnsend_tim)
+!***
+!*** Apply beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfilt_tim)
+ call this%sup_vrbeta1_bkg(km,km3,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfilt_tim)
+ endif
+!-----------------------------------------------------------------------
+endsubroutine filtering_lin2_bkg
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filtering_fast_bkg(this)
+!***********************************************************************
+! !
+! Fast multigrid filtering procedure: !
+! !
+! - Apply adjoint of vertical filter before and directec vertical !
+! filter after horizontal !
+! - 1d+1d horizontal filter !
+! !
+!***********************************************************************
+implicit none
+class (mg_intstate_type),target::this
+integer(i_kind) L,i,j
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+!***
+!*** Adjoint of beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfiltT_tim)
+ call this%sup_vrbeta1T_bkg(km,km3,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfiltT_tim)
+ endif
+!***
+!*** Adjoint interpolate and upsend
+!***
+ call btim(upsend_tim)
+ call this%upsending_all(VALL,HALL,lquart)
+ call etim(upsend_tim)
+!***
+!*** Apply adjoint of Beta filter at all generations
+!***
+ call btim(hfiltT_tim)
+ do i=im,1,-1
+ call this%rbetaT(km,hy,1,jm,paspy,ssy,VALL(:,i,:))
+ enddo
+ call etim(hfiltT_tim)
+ call btim(bocoT_tim)
+ call this%bocoTy(VALL,km,im,jm,hx,hy)
+ call etim(bocoT_tim)
+ call btim(hfiltT_tim)
+ do j=jm,1,-1
+ call this%rbetaT(km,hx,1,im,paspx,ssx,VALL(:,:,j))
+ enddo
+ call etim(hfiltT_tim)
+ call btim(bocoT_tim)
+ call this%bocoTx(VALL,km,im,jm,hx,hy)
+ call etim(bocoT_tim)
+ if(l_hgen) then
+ call btim(hfiltT_tim)
+ do i=im,1,-1
+ call this%rbetaT(km,hy,1,jm,paspy,ssy,HALL(:,i,:))
+ enddo
+ call etim(hfiltT_tim)
+ endif
+ call btim(bocoT_tim)
+ call this%bocoTy(HALL,km,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(bocoT_tim)
+ if(l_hgen) then
+ call btim(hfiltT_tim)
+ do j=jm,1,-1
+ call this%rbetaT(km,hx,1,im,paspx,ssx,HALL(:,:,j))
+ enddo
+ call etim(hfiltT_tim)
+ endif
+ call btim(bocoT_tim)
+ call this%bocoTx(HALL,km,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(bocoT_tim)
+!***
+!*** Apply (a-b\nabla^2)
+!***
+ call btim(weight_tim)
+ call this%weighting_all(VALL,HALL,lhelm)
+ call etim(weight_tim)
+!***
+!*** Apply Beta filter at all generations
+!***
+ call btim(boco_tim)
+ call this%bocox(VALL,km,im,jm,hx,hy)
+ call etim(boco_tim)
+ call btim(hfilt_tim)
+ do j=1,jm
+ call this%rbeta(km,hx,1,im,paspx,ssx,VALL(:,:,j))
+ enddo
+ call etim(hfilt_tim)
+ call btim(boco_tim)
+ call this%bocoy(VALL,km,im,jm,hx,hy)
+ call etim(boco_tim)
+ call btim(hfilt_tim)
+ do i=1,im
+ call this%rbeta(km,hy,1,jm,paspy,ssy,VALL(:,i,:))
+ enddo
+ call etim(hfilt_tim)
+ call btim(boco_tim)
+ call this%bocox(HALL,km,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(boco_tim)
+ if(l_hgen) then
+ call btim(hfilt_tim)
+ do j=1,jm
+ call this%rbeta(km,hx,1,im,paspx,ssx,HALL(:,:,j))
+ enddo
+ call etim(hfilt_tim)
+ endif
+ call btim(boco_tim)
+ call this%bocoy(HALL,km,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(boco_tim)
+ if(l_hgen) then
+ call btim(hfilt_tim)
+ do i=1,im
+ call this%rbeta(km,hy,1,jm,paspy,ssy,HALL(:,i,:))
+ enddo
+ call etim(hfilt_tim)
+ endif
+!***
+!*** Downsend, interpolate and add, then zero high generations
+!***
+ call btim(dnsend_tim)
+ call this%downsending_all(HALL,VALL,lquart)
+ call etim(dnsend_tim)
+!***
+!*** Apply beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfilt_tim)
+ call this%sup_vrbeta1_bkg(km,km3,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfilt_tim)
+ endif
+!-----------------------------------------------------------------------
+endsubroutine filtering_fast_bkg
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filtering_rad2_ens(this,mg_filt_flag)
+!***********************************************************************
+! !
+! Multigrid filtering procedure for ensemble: !
+! !
+! - Apply vertical filter before and after horizontal !
+! - 2d radial filter !
+! - Version for localization of ensemble !
+! !
+!***********************************************************************
+implicit none
+class (mg_intstate_type),target::this
+integer(i_kind),intent(in):: mg_filt_flag
+integer(i_kind) L,i,j
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+if(mg_filt_flag==1) then
+ call btim(upsend_tim)
+ call this%upsending_ens_nearest(VALL,HALL,km_all)
+ call etim(upsend_tim)
+else
+!***
+!*** Adjoint of beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfiltT_tim)
+ call this%sup_vrbeta1T_ens(km3_all,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfiltT_tim)
+ endif
+!***
+!*** Adjoint interpolate and upsend
+!***
+ call btim(upsend_tim)
+ if(lquart) then
+ call this%upsending2_ens(VALL,HALL,km_all)
+ else
+ call this%upsending_ens(VALL,HALL,km_all)
+ endif
+ call etim(upsend_tim)
+!***
+!*** Apply adjoint of Beta filter at all generations
+!***
+ call btim(hfiltT_tim)
+ if(l_filt_g1) then
+ call this%rbetaT(km_all,hx,1,im,hy,1,jm,pasp2,ss2,VALL(:,:,:))
+ endif
+ if(l_hgen) then
+ call this%rbetaT(km_all,hx,1,im,hy,1,jm,pasp2,ss2,HALL(:,:,:))
+ endif
+ call etim(hfiltT_tim)
+
+ call btim(bocoT_tim)
+ if(l_filt_g1) then
+ call this%bocoT_2d(VALL,km_all,im,jm,hx,hy)
+ endif
+ call this%bocoT_2d(HALL,km_all,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(bocoT_tim)
+endif
+!***
+!*** Apply (a-b\nabla^2)
+!***
+ call btim(weight_tim)
+ call this%weighting_ens(VALL,HALL,km_all)
+ call etim(weight_tim)
+
+if(mg_filt_flag==-1) then
+ call btim(dnsend_tim)
+ call this%downsending_ens_nearest(HALL,VALL,km_all)
+ call etim(dnsend_tim)
+else
+!***
+!*** Apply Beta filter at all generations
+!***
+ call btim(boco_tim)
+ if(l_filt_g1) then
+ call this%boco_2d(VALL,km_all,im,jm,hx,hy)
+ endif
+ call this%boco_2d(HALL,km_all,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(boco_tim)
+
+ call btim(hfilt_tim)
+ if(l_filt_g1) then
+ call this%rbeta(km_all,hx,1,im,hy,1,jm,pasp2,ss2,VALL(:,:,:))
+ endif
+ if(l_hgen) then
+ call this%rbeta(km_all,hx,1,im,hy,1,jm,pasp2,ss2,HALL(:,:,:))
+ endif
+ call etim(hfilt_tim)
+!***
+!*** Downsend, interpolate and add, then zero high generations
+!***
+ call btim(dnsend_tim)
+ if(lquart) then
+ call this%downsending2_ens(HALL,VALL,km_all)
+ else
+ call this%downsending_ens(HALL,VALL,km_all)
+ endif
+ call etim(dnsend_tim)
+!***
+!*** Apply beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfilt_tim)
+ call this%sup_vrbeta1_ens(km3_all,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfilt_tim)
+ endif
+endif
+!-----------------------------------------------------------------------
+endsubroutine filtering_rad2_ens
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filtering_lin2_ens(this,mg_filt_flag)
+!***********************************************************************
+! !
+! Multigrid filtering procedure for ensemble: !
+! !
+! - Vertical filter before and after horizontal !
+! - Line filters in horizontal !
+! - Version for localization of ensemble !
+! !
+!***********************************************************************
+implicit none
+class (mg_intstate_type),target::this
+integer(i_kind),intent(in):: mg_filt_flag
+integer(i_kind) L,i,j
+integer(i_kind) icol,iout,jout
+logical:: ff
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+if(mg_filt_flag==1) then
+ call btim(upsend_tim)
+ call this%upsending_ens_nearest(VALL,HALL,km_all)
+ call etim(upsend_tim)
+else
+!***
+!*** Adjoint of beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfiltT_tim)
+ call this%sup_vrbeta1T_ens(km3_all,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfiltT_tim)
+ endif
+!***
+!*** Adjoint interpolate and upsend
+!***
+ call btim(upsend_tim)
+ if(lquart) then
+ call this%upsending2_ens(VALL,HALL,km_all)
+ else
+ call this%upsending_ens(VALL,HALL,km_all)
+ endif
+ call etim(upsend_tim)
+!***
+!*** Apply adjoint of Beta filter at all generations
+!***
+ if(l_filt_g1) then
+ do icol=3,1,-1
+ call btim(hfiltT_tim)
+ call dibetat(km_all,1-hx,1,im,im+hx,1-hy,1,jm,jm+hy,nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol),VALL,ff,iout,jout)
+ call etim(hfiltT_tim)
+ call btim(bocoT_tim)
+ call this%bocoT_2d(VALL,km_all,im,jm,hx,hy)
+ call etim(bocoT_tim)
+ enddo
+ endif
+
+ do icol=3,1,-1
+ if(l_hgen) then
+ call btim(hfiltT_tim)
+ call dibetat(km_all,1-hx,1,im,im+hx,1-hy,1,jm,jm+hy,nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol),HALL,ff,iout,jout)
+ call etim(hfiltT_tim)
+ endif
+ call btim(bocoT_tim)
+ call this%bocoT_2d(HALL,km_all,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(bocoT_tim)
+ enddo
+endif
+!***
+!*** Apply (a-b\nabla^2)
+!***
+ call btim(weight_tim)
+ call this%weighting_ens(VALL,HALL,km_all)
+ call etim(weight_tim)
+
+if(mg_filt_flag==-1) then
+ call btim(dnsend_tim)
+ call this%downsending_ens_nearest(HALL,VALL,km_all)
+ call etim(dnsend_tim)
+else
+!***
+!*** Apply Beta filter at all generations
+!***
+ if(l_filt_g1) then
+ do icol=1,3
+ call btim(boco_tim)
+ call this%boco_2d(VALL,km_all,im,jm,hx,hy)
+ call etim(boco_tim)
+ call btim(hfilt_tim)
+ call dibeta(km_all,1-hx,1,im,im+hx,1-hy,1,jm,jm+hy,nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol),VALL,ff,iout,jout)
+ call etim(hfilt_tim)
+ enddo
+ endif
+
+ do icol=1,3
+ call btim(boco_tim)
+ call this%boco_2d(HALL,km_all,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(boco_tim)
+ if(l_hgen) then
+ call btim(hfilt_tim)
+ call dibeta(km_all,1-hx,1,im,im+hx,1-hy,1,jm,jm+hy,nfil, &
+ dixs(:,:,icol),diys(:,:,icol),hss2(:,:,icol),HALL,ff,iout,jout)
+ call etim(hfilt_tim)
+ endif
+ enddo
+!***
+!*** Downsend, interpolate and add, then zero high generations
+!***
+ call btim(dnsend_tim)
+ if(lquart) then
+ call this%downsending2_ens(HALL,VALL,km_all)
+ else
+ call this%downsending_ens(HALL,VALL,km_all)
+ endif
+ call etim(dnsend_tim)
+!***
+!*** Apply beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfilt_tim)
+ call this%sup_vrbeta1_ens(km3_all,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfilt_tim)
+ endif
+endif
+!-----------------------------------------------------------------------
+endsubroutine filtering_lin2_ens
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filtering_fast_ens(this,mg_filt_flag)
+!***********************************************************************
+! !
+! Fast multigrid filtering procedure for ensemble: !
+! !
+! - Apply vertical filter before and after horizontal !
+! - 1d+1d horizontal filter + 1d vertical filter !
+! - Version for localizaiton of ensemble !
+! !
+!***********************************************************************
+implicit none
+class (mg_intstate_type),target::this
+integer(i_kind),intent(in):: mg_filt_flag
+integer(i_kind) L,i,j
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+if(mg_filt_flag==1) then
+ call btim(upsend_tim)
+ call this%upsending_ens_nearest(VALL,HALL,km_all)
+ call etim(upsend_tim)
+else
+!***
+!*** Adjoint of beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfiltT_tim)
+ call this%sup_vrbeta1T_ens(km3_all,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfiltT_tim)
+ endif
+!***
+!*** Adjoint interpolate and upsend
+!***
+ call btim(upsend_tim)
+ if(lquart) then
+ call this%upsending2_ens(VALL,HALL,km_all)
+ else
+ call this%upsending_ens(VALL,HALL,km_all)
+ endif
+ call etim(upsend_tim)
+!***
+!*** Apply adjoint of Beta filter at all generations
+!***
+ if(l_filt_g1) then
+ call btim(hfiltT_tim)
+ do i=im,1,-1
+ call this%rbetaT(km_all,hy,1,jm,paspy,ssy,VALL(:,i,:))
+ enddo
+ call etim(hfiltT_tim)
+ call btim(bocoT_tim)
+ call this%bocoTy(VALL,km_all,im,jm,hx,hy)
+ call etim(bocoT_tim)
+ call btim(hfiltT_tim)
+ do j=jm,1,-1
+ call this%rbetaT(km_all,hx,1,im,paspx,ssx,VALL(:,:,j))
+ enddo
+ call etim(hfiltT_tim)
+ call btim(bocoT_tim)
+ call this%bocoTx(VALL,km_all,im,jm,hx,hy)
+ call etim(bocoT_tim)
+ endif
+ if(l_hgen) then
+ call btim(hfiltT_tim)
+ do i=im,1,-1
+ call this%rbetaT(km_all,hy,1,jm,paspy,ssy,HALL(:,i,:))
+ enddo
+ call etim(hfiltT_tim)
+ endif
+ call btim(bocoT_tim)
+ call this%bocoTy(HALL,km_all,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(bocoT_tim)
+ if(l_hgen) then
+ call btim(hfiltT_tim)
+ do j=jm,1,-1
+ call this%rbetaT(km_all,hx,1,im,paspx,ssx,HALL(:,:,j))
+ enddo
+ call etim(hfiltT_tim)
+ endif
+ call btim(bocoT_tim)
+ call this%bocoTx(HALL,km_all,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(bocoT_tim)
+endif
+!***
+!*** Apply (a-b\nabla^2)
+!***
+ call btim(weight_tim)
+ call this%weighting_ens(VALL,HALL,km_all)
+ call etim(weight_tim)
+
+if(mg_filt_flag==-1) then
+ call btim(dnsend_tim)
+ call this%downsending_ens_nearest(HALL,VALL,km_all)
+ call etim(dnsend_tim)
+else
+!***
+!*** Apply Beta filter at all generations
+!***
+ if(l_filt_g1) then
+ call btim(boco_tim)
+ call this%bocox(VALL,km_all,im,jm,hx,hy)
+ call etim(boco_tim)
+ call btim(hfilt_tim)
+ do j=1,jm
+ call this%rbeta(km_all,hx,1,im,paspx,ssx,VALL(:,:,j))
+ enddo
+ call etim(hfilt_tim)
+ call btim(boco_tim)
+ call this%bocoy(VALL,km_all,im,jm,hx,hy)
+ call etim(boco_tim)
+ call btim(hfilt_tim)
+ do i=1,im
+ call this%rbeta(km_all,hy,1,jm,paspy,ssy,VALL(:,i,:))
+ enddo
+ call etim(hfilt_tim)
+ endif
+ call btim(boco_tim)
+ call this%bocox(HALL,km_all,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(boco_tim)
+ if(l_hgen) then
+ call btim(hfilt_tim)
+ do j=1,jm
+ call this%rbeta(km_all,hx,1,im,paspx,ssx,HALL(:,:,j))
+ enddo
+ call etim(hfilt_tim)
+ endif
+ call btim(boco_tim)
+ call this%bocoy(HALL,km_all,im,jm,hx,hy,Fimax,Fjmax,2,gm)
+ call etim(boco_tim)
+ if(l_hgen) then
+ call btim(hfilt_tim)
+ do i=1,im
+ call this%rbeta(km_all,hy,1,jm,paspy,ssy,HALL(:,i,:))
+ enddo
+ call etim(hfilt_tim)
+ endif
+!***
+!*** Downsend, interpolate and add, then zero high generations
+!***
+ call btim(dnsend_tim)
+ if(lquart) then
+ call this%downsending2_ens(HALL,VALL,km_all)
+ else
+ call this%downsending_ens(HALL,VALL,km_all)
+ endif
+ call etim(dnsend_tim)
+!***
+!*** Apply beta filter in vertical direction
+!***
+ if(l_vertical_filter) then
+ call btim(vfilt_tim)
+ call this%sup_vrbeta1_ens(km3_all,hx,hy,hz,im,jm,lm,pasp1,ss1,VALL)
+ call etim(vfilt_tim)
+ endif
+endif
+!-----------------------------------------------------------------------
+endsubroutine filtering_fast_ens
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filtering_rad_highest(this)
+!***********************************************************************
+! !
+! Multigrid filtering procedure: !
+! !
+! - 2d radial filter only for the highest generation !
+! - Without horizontal parallelization !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target:: this
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!-----------------------------------------------------------------------
+
+!***
+!*** Adjoint interpolate and upsend
+!***
+ call btim(upsend_tim)
+ call this%upsending_highest(VALL,HALL)
+ call etim(upsend_tim)
+!***
+!*** Apply adjoint of Beta filter at all generations
+!***
+ call btim(hfiltT_tim)
+ call this%rbetaT(km,hx,1,imH,hy,1,jmH,&
+ &pasp2(:,:,1:imH,1:jmH),ss2(1:imH,1:jmH),HALL(:,1-hx:imH+hx,1-hy:jmH+hy))
+ call etim(hfiltT_tim)
+!***
+!*** Apply (a-b\nabla^2)
+!***
+ call btim(weight_tim)
+ call this%weighting_highest(HALL(:,1-hx:imH+hx,1-hy:jmH+hy))
+ call etim(weight_tim)
+!***
+!*** Apply Beta filter at all generations
+!***
+ call btim(hfilt_tim)
+ call this%rbeta(km,hx,1,imH,hy,1,jmH,&
+ &pasp2(:,:,1:imH,1:jmH),ss2(1:imH,1:jmH),HALL(:,1-hx:imH+hx,1-hy:jmH+hy))
+ call etim(hfilt_tim)
+!***
+!*** Downsend, interpolate and add, then zero high generations
+!***
+ call btim(dnsend_tim)
+ call this%downsending_highest(HALL,VALL)
+ call etim(dnsend_tim)
+
+!-----------------------------------------------------------------------
+endsubroutine filtering_rad_highest
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine sup_vrbeta1 &
+!**********************************************************************
+! *
+! conversion of vrbeta1 *
+! *
+!**********************************************************************
+(this,kmax,hx,hy,hz,im,jm,lm,pasp,ss,V)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: kmax,hx,hy,hz,im,jm,lm
+real(r_kind),dimension(1:kmax,1-hx:im+hx,1-hy:jm+hy,1:lm),intent(inout):: V
+real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+real(r_kind),dimension(1:lm), intent(in):: ss
+real(r_kind),dimension(1:kmax,1-hz:lm+hz):: W
+integer(i_kind):: i,j,L
+!----------------------------------------------------------------------
+
+ do j=1,jm
+ do i=1,im
+ do L=1,Lm
+ W(:,L)=V(:,i,j,L)
+ end do
+ do L=1,hz
+ W(:,1-L)=W(:,1+L)
+ W(:,LM+L)=W(:,LM-L)
+ end do
+ call this%rbeta(kmax,hz,1,lm, pasp,ss,W)
+ do l=1,Lm
+ V(:,i,j,L)=W(:,L)
+ end do
+ end do
+ end do
+
+!----------------------------------------------------------------------
+endsubroutine sup_vrbeta1
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine sup_vrbeta1T &
+!**********************************************************************
+! *
+! Adjoint of sup_vrbeta1 *
+! *
+!**********************************************************************
+(this,kmax,hx,hy,hz,im,jm,lm,pasp,ss,V)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: kmax,hx,hy,hz,im,jm,lm
+real(r_kind),dimension(1:kmax,1-hx:im+hx,1-hy:jm+hy,1:lm),intent(inout):: V
+real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+real(r_kind),dimension(1:lm), intent(in):: ss
+real(r_kind),dimension(1:kmax,1-hz:lm+hz):: W
+integer(i_kind):: i,j,L
+!----------------------------------------------------------------------
+
+ do j=1,jm
+ do i=1,im
+ do L=1,Lm
+ W(:,L)=V(:,i,j,L)
+ end do
+ do L=1,hz
+ W(:,1-L )=W(:,1+L )
+ W(:,LM+L)=W(:,LM-L)
+ end do
+ call this%rbetaT(kmax,hz,1,lm, pasp,ss,W)
+!
+! Apply adjoint at the edges of domain
+!
+ do L=1,hz
+ W(:,1+L)=W(:,1+L)+W(:,1-L)
+ W(:,LM-L)=W(:,LM-L)+W(:,LM+L)
+ enddo
+ do l=1,Lm
+ V(:,i,j,L)=W(:,L)
+ end do
+ end do
+ end do
+
+!----------------------------------------------------------------------
+endsubroutine sup_vrbeta1T
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine sup_vrbeta3 &
+!**********************************************************************
+! *
+! conversion of vrbeta3 *
+! *
+!**********************************************************************
+(this,kmax,hx,hy,hz,im,jm,lm,pasp,ss,V)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: kmax,hx,hy,hz,im,jm,lm
+real(r_kind),dimension(1:kmax,1-hx:im+hx,1-hy:jm+hy,1:lm),intent(inout):: V
+real(r_kind),dimension(3,3,1:im,1:jm,1:lm), intent(in):: pasp
+real(r_kind),dimension(1:im,1:jm,1:lm), intent(in):: ss
+real(r_kind),dimension(1:kmax,1-hx:im+hx,1-hy:jm+hy,1-hz:lm+hz):: W
+integer(i_kind):: i,j,L
+!----------------------------------------------------------------------
+
+ do L=1,Lm
+ do j=1-hy,jm+hy
+ do i=1-hx,im+hx
+ W(:,i,j,L)=V(:,i,j,L)
+ end do
+ end do
+ end do
+
+ do L=1,hz
+ do j=1-hy,jm+hy
+ do i=1-hx,im+hx
+ W(:,i,j,1-L )=W(:,i,j,1+L )
+ W(:,i,j,LM+L)=W(:,i,j,LM-L)
+ end do
+ end do
+ end do
+
+
+ call this%rbeta(kmax,hx,1,im, hy,1,jm, hz,1,lm, pasp,ss,W)
+
+
+ do l=1,Lm
+ do j=1,jm
+ do i=1,im
+ V(:,i,j,L)=W(:,i,j,L)
+ end do
+ end do
+ end do
+
+!----------------------------------------------------------------------
+endsubroutine sup_vrbeta3
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine sup_vrbeta3T &
+!**********************************************************************
+! *
+! Adjoint of sup_vrbeta3 *
+! *
+!**********************************************************************
+(this,kmax,hx,hy,hz,im,jm,lm,pasp,ss,V)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: kmax,hx,hy,hz,im,jm,lm
+real(r_kind),dimension(1:kmax,1-hx:im+hx,1-hy:jm+hy,1:lm),intent(inout):: V
+real(r_kind),dimension(3,3,1:im,1:jm,1:lm), intent(in):: pasp
+real(r_kind),dimension(1:im,1:jm,1:lm), intent(in):: ss
+real(r_kind),dimension(1:kmax,1-hx:im+hx,1-hy:jm+hy,1-hz:lm+hz):: W
+integer(i_kind):: i,j,l
+!----------------------------------------------------------------------
+
+ do L=1,Lm
+ do j=1-hy,jm+hy
+ do i=1-hx,im+hx
+ W(:,i,j,L)=V(:,i,j,L)
+ end do
+ end do
+ end do
+
+ do L=1,hz
+ do j=1-hy,jm+hy
+ do i=1-hx,im+hx
+ W(:,i,j,1-L )=W(:,i,j, 1+L)
+ W(:,i,j,LM+L)=W(:,i,j,LM-L)
+ end do
+ end do
+ end do
+
+
+ call this%rbetaT(kmax,hx,1,im, hy,1,jm, hz,1,lm, pasp,ss,W)
+
+!
+! Apply adjoint at the edges of domain
+!
+ do L=1,hz
+ do j=1-hy,jm+hy
+ do i=1-hx,im+hx
+ W(:,i,j,1+L )=W(:,i,j, 1+L)+W(:,i,j, 1-L)
+ W(:,i,j,LM-L)=W(:,i,j,LM-L)+W(:,i,j,LM+L)
+ end do
+ end do
+ end do
+
+ do l=1,lm
+ do j=1,jm
+ do i=1,im
+ V(:,i,j,l)=W(:,i,j,l)
+ end do
+ end do
+ end do
+
+!----------------------------------------------------------------------
+endsubroutine sup_vrbeta3T
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine sup_vrbeta1_ens &
+!**********************************************************************
+! *
+! conversion of vrbeta1 *
+! *
+!**********************************************************************
+(this,km_en,hx,hy,hz,im,jm,lm,pasp,ss,VALL)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: km_en,hx,hy,hz,im,jm,lm
+real(r_kind),dimension(1:km_en*lm,1-hx:im+hx,1-hy:jm+hy),intent(inout):: VALL
+real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+real(r_kind),dimension(1:lm), intent(in):: ss
+real(r_kind),dimension(1:km_en,1-hz:lm+hz):: W
+integer(i_kind):: i,j,L,k,k_ind,kloc
+!----------------------------------------------------------------------
+
+ do j=1,jm
+ do i=1,im
+ do k=1,km_en
+ k_ind =(k-1)*Lm
+ do L=1,Lm
+ kloc=k_ind+L
+ W(k,L)=VALL(kloc,i,j)
+ end do
+ enddo
+ do L=1,hz
+ W(:,1-L )=W(:,1+L )
+ W(:,LM+L)=W(:,LM-L)
+ end do
+
+ call this%rbeta(km_en,hz,1,lm, pasp,ss,W)
+
+ do k=1,km_en
+ k_ind =(k-1)*Lm
+ do L=1,Lm
+ kloc=k_ind+L
+ VALL(kloc,i,j)= W(k,L)
+ end do
+ enddo
+ enddo
+ enddo
+
+!----------------------------------------------------------------------
+endsubroutine sup_vrbeta1_ens
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine sup_vrbeta1T_ens &
+!**********************************************************************
+! *
+! Adjoint of sup_vrbeta1_ens *
+! *
+!**********************************************************************
+(this,km_en,hx,hy,hz,im,jm,lm,pasp,ss,VALL)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: km_en,hx,hy,hz,im,jm,lm
+real(r_kind),dimension(1:km_en*lm,1-hx:im+hx,1-hy:jm+hy),intent(inout):: VALL
+real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+real(r_kind),dimension(1:lm), intent(in):: ss
+real(r_kind),dimension(1:km_en,1-hz:lm+hz):: W
+integer(i_kind):: i,j,L,k,k_ind,kloc
+!----------------------------------------------------------------------
+
+ do j=1,jm
+ do i=1,im
+
+ do k=1,km_en
+ k_ind = (k-1)*Lm
+ do L=1,Lm
+ kloc=k_ind+L
+ W(k,L)=VALL(kloc,i,j)
+ end do
+ enddo
+ do L=1,hz
+ W(:,1-L )=W(:,1+L )
+ W(:,LM+L)=W(:,LM-L)
+ end do
+
+ call this%rbetaT(km_en,hz,1,lm, pasp,ss,W)
+!
+! Apply adjoint at the edges of domain
+!
+ do L=1,hz
+ W(:,1+L )=W(:,1+L )+W(:,1-L)
+ W(:,LM-L)=W(:,LM-L)+W(:,LM+L)
+ enddo
+
+ do k=1,km_en
+ k_ind = (k-1)*Lm
+ do l=1,Lm
+ kloc=k_ind+L
+ VALL(kloc,i,j)=W(k,L)
+ enddo
+ end do
+
+ end do
+ end do
+
+!----------------------------------------------------------------------
+endsubroutine sup_vrbeta1T_ens
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine sup_vrbeta1_bkg &
+!**********************************************************************
+! *
+! conversion of vrbeta1 *
+! *
+!**********************************************************************
+(this,km,km3,hx,hy,hz,im,jm,lm,pasp,ss,VALL)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: km,km3,hx,hy,hz,im,jm,lm
+real(r_kind),dimension(1:km,1-hx:im+hx,1-hy:jm+hy),intent(inout):: VALL
+real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+real(r_kind),dimension(1:lm), intent(in):: ss
+real(r_kind),dimension(1:km3,1-hz:lm+hz):: W
+integer(i_kind):: i,j,L,k,k_ind,kloc
+!----------------------------------------------------------------------
+
+ do j=1,jm
+ do i=1,im
+ do k=1,km3
+ k_ind =(k-1)*Lm
+ do L=1,Lm
+ kloc=k_ind+L
+ W(k,L)=VALL(kloc,i,j)
+ end do
+ enddo
+ do L=1,hz
+ W(:,1-L )=W(:,1+L )
+ W(:,LM+L)=W(:,LM-L)
+ end do
+
+ call this%rbeta(km3,hz,1,lm, pasp,ss,W)
+
+ do k=1,km3
+ k_ind =(k-1)*Lm
+ do L=1,Lm
+ kloc=k_ind+L
+ VALL(kloc,i,j)= W(k,L)
+ end do
+ enddo
+ enddo
+ enddo
+
+!----------------------------------------------------------------------
+endsubroutine sup_vrbeta1_bkg
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine sup_vrbeta1T_bkg &
+!**********************************************************************
+! *
+! Adjoint of sup_vrbeta1_bkg *
+! *
+!**********************************************************************
+(this,km,km3,hx,hy,hz,im,jm,lm,pasp,ss,VALL)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: km,km3,hx,hy,hz,im,jm,lm
+real(r_kind),dimension(1:km,1-hx:im+hx,1-hy:jm+hy),intent(inout):: VALL
+real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+real(r_kind),dimension(1:lm), intent(in):: ss
+real(r_kind),dimension(1:km3,1-hz:lm+hz):: W
+integer(i_kind):: i,j,L,k,k_ind,kloc
+!----------------------------------------------------------------------
+
+ do j=1,jm
+ do i=1,im
+
+ do k=1,km3
+ k_ind = (k-1)*Lm
+ do L=1,Lm
+ kloc=k_ind+L
+ W(k,L)=VALL(kloc,i,j)
+ end do
+ enddo
+ do L=1,hz
+ W(:,1-L )=W(:,1+L )
+ W(:,LM+L)=W(:,LM-L)
+ end do
+
+ call this%rbetaT(km3,hz,1,lm, pasp,ss,W)
+!
+! Apply adjoint at the edges of domain
+!
+ do L=1,hz
+ W(:,1+L )=W(:,1+L )+W(:,1-L)
+ W(:,LM-L)=W(:,LM-L)+W(:,LM+L)
+ enddo
+
+ do k=1,km3
+ k_ind = (k-1)*Lm
+ do l=1,Lm
+ kloc=k_ind+L
+ VALL(kloc,i,j)=W(k,L)
+ enddo
+ end do
+
+ end do
+ end do
+
+!----------------------------------------------------------------------
+endsubroutine sup_vrbeta1T_bkg
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+end submodule mg_filtering
diff --git a/src/mgbf/mg_generations.f90 b/src/mgbf/mg_generations.f90
new file mode 100644
index 0000000000..2008a75289
--- /dev/null
+++ b/src/mgbf/mg_generations.f90
@@ -0,0 +1,1756 @@
+submodule(mg_intstate) mg_generations
+!$$$ submodule documentation block
+! . . . .
+! module: mg_generations
+! prgmmr: rancic org: NCEP/EMC date: 2022
+!
+! abstract: Contains procedures that include differrent generations
+! (offset version)
+!
+! module history log:
+! 2023-04-19 lei - object-oriented coding
+! 2024-01-11 rancic - optimization for ensemble localization
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! upsending_all -
+! downsending_all -
+! weighting_all -
+! upsending -
+! downsending -
+! upsending_highest -
+! downsending_highest -
+! upsending2 -
+! downsending2 -
+! upsending_ens -
+! downsending_ens -
+! upsending_ens_nearest -
+! downsending_ens_nearest -
+! upsending2_ens -
+! downsending2_ens -
+! upsending_loc_g3 -
+! upsending_loc_g4 -
+! downsending_loc_g3 -
+! downsending_loc_g4 -
+! weighting_helm -
+! weighting -
+! weighting_highest -
+! weighting_ens -
+! weighting_loc_g3 -
+! weighting_loc_g4 -
+! adjoint -
+! direct1 -
+! adjoint2 -
+! direct2 -
+! adjoint_nearest -
+! direct_nearest -
+! adjoint_highest -
+! direct_highest -
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+!***********************************************************************
+! !
+! !
+! M. Rancic (2022) !
+!***********************************************************************
+use mpi
+use kinds, only: r_kind,i_kind
+use mg_timers
+!TEST
+use, intrinsic:: ieee_arithmetic
+!TEST
+
+interface weighting_loc
+ module procedure weighting_loc_g3
+ module procedure weighting_loc_g4
+endinterface
+
+interface upsending_loc
+ module procedure upsending_loc_g3
+ module procedure upsending_loc_g4
+endinterface
+
+interface downsending_loc
+ module procedure downsending_loc_g3
+ module procedure downsending_loc_g4
+endinterface
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+contains
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsending_all &
+!***********************************************************************
+! !
+! Adjoint interpolate and upsend: !
+! !
+!***********************************************************************
+(this,V,H,lquart)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+logical, intent(in):: lquart
+!-----------------------------------------------------------------------
+
+ if(lquart) then
+ call this%upsending2(V,H)
+ else
+ call this%upsending(V,H)
+ endif
+
+!-----------------------------------------------------------------------
+endsubroutine upsending_all
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsending_all &
+!***********************************************************************
+! !
+! Downsend, interpolate and add: !
+! First from gm->g3...->g2 !
+! Then from g2->g1 !
+! !
+!***********************************************************************
+(this,H,V,lquart)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+logical, intent(in):: lquart
+!-----------------------------------------------------------------------
+
+ if(lquart) then
+ call this%downsending2(H,V)
+ else
+ call this%downsending(H,V)
+ endif
+
+!-----------------------------------------------------------------------
+endsubroutine downsending_all
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine weighting_all &
+!***********************************************************************
+! !
+! Apply 2D differential operator to compound variable !
+! !
+!***********************************************************************
+(this,V,H,lhelm)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+logical, intent(in):: lhelm
+!-----------------------------------------------------------------------
+
+ if(lhelm) then
+ call this%weighting_helm(V,H)
+ else
+ call this%weighting(V,H)
+ endif
+
+!-----------------------------------------------------------------------
+endsubroutine weighting_all
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsending &
+!***********************************************************************
+! !
+! Adjoint interpolate and upsend: !
+! First from g1->g2 (V -> H) !
+! Then from g2->...->gn (H -> H) !
+! !
+!***********************************************************************
+(this,V,H)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+real(r_kind),dimension(this%km,-1:this%imL+2,-1:this%jmL+2):: V_INT
+real(r_kind),dimension(this%km,-1:this%imL+2,-1:this%jmL+2):: H_INT
+integer(i_kind):: g,L
+!-----------------------------------------------------------------------
+!
+! From generation 1 to generation 2
+!
+
+ call this%adjoint(V(1:this%km,1:this%im,1:this%jm),V_INT,this%km,1)
+
+ call this%bocoT_2d(V_INT,this%km,this%imL,this%jmL,2,2)
+
+ call this%upsend_all(V_INT(1:this%km,1:this%imL,1:this%jmL),H,this%km)
+!
+! From generation 2 sequentially to higher generations
+!
+ do g=2,this%gm-1
+
+ if(g==this%my_hgen) then
+ call this%adjoint(H(1:this%km,1:this%im,1:this%jm),H_INT,this%km,g)
+ endif
+
+ call this%bocoT_2d(H_INT,this%km,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,g,g)
+
+ call this%upsend_all(H_INT(1:this%km,1:this%imL,1:this%jmL),H,this%km,g,g+1)
+
+ end do
+
+!-----------------------------------------------------------------------
+endsubroutine upsending
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsending &
+!***********************************************************************
+! !
+! Downsend, interpolate and add: !
+! First from gm->g3...->g2 !
+! Then from g2->g1 !
+! !
+!***********************************************************************
+(this,H,V)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(this%km,-1:this%imL+2,-1:this%jmL+2):: H_INT
+real(r_kind),dimension(this%km,-1:this%imL+2,-1:this%jmL+2):: V_INT
+real(r_kind),dimension(this%km,1:this%im,1:this%jm):: H_PROX
+real(r_kind),dimension(this%km,1:this%im,1:this%jm):: V_PROX
+integer(i_kind):: g,l,k
+integer(i_kind):: iL,jL,i,j
+!-----------------------------------------------------------------------
+!
+! Upper generations
+!
+ do g=this%gm,3,-1
+
+ call this%downsend_all(H(1:this%km,1:this%im,1:this%jm),H_INT(1:this%km,1:this%imL,1:this%jmL),this%km,g,g-1)
+ call this%boco_2d(H_INT,this%km,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,g-1,g-1)
+
+ if(this%my_hgen==g-1) then
+ call this%direct1(H_INT,H_PROX,this%km,g-1)
+ H(1:this%km,1:this%im,1:this%jm)=H (1:this%km,1:this%im,1:this%jm) &
+ +H_PROX(1:this%km,1:this%im,1:this%jm)
+ endif
+
+ enddo
+
+!
+! From geneartion 2 to generation 1
+!
+
+ call this%downsend_all(H(1:this%km,1:this%im,1:this%jm),V_INT(1:this%km,1:this%imL,1:this%jmL),this%km)
+ H(:,:,:)=0.
+
+ call this%boco_2d(V_INT,this%km,this%imL,this%jmL,2,2)
+
+ call this%direct1(V_INT,V_PROX,this%km,1)
+
+ V(1:this%km,1:this%im,1:this%jm)=V (1:this%km,1:this%im,1:this%jm) &
+ +V_PROX(1:this%km,1:this%im,1:this%jm)
+
+!-----------------------------------------------------------------------
+endsubroutine downsending
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsending_highest &
+!***********************************************************************
+! !
+! Adjoint interpolate and upsend: !
+! First from g1->g2 (V -> H) !
+! Then from g2->...->gn (H -> H) !
+! !
+!***********************************************************************
+(this,V,H)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+real(r_kind),dimension(this%km,-1:this%imL+2,-1:this%jmL+2):: H_INT
+integer(i_kind):: g
+!-----------------------------------------------------------------------
+!
+! From generation 1 to higher generations
+!
+ H(:,:,:)=0.
+ H(1:this%km,1:this%im0(1),1:this%jm0(1))=V(1:this%km,1:this%im0(1),1:this%jm0(1))
+ do g=1,this%gm-1
+ call this%adjoint_highest(H(1:this%km,1:this%im0(g),1:this%jm0(g)),&
+ & H_INT(1:this%km,-1:this%im0(g+1)+2,-1:this%jm0(g+1)+2),this%km,g)
+ H(1:this%km,1:this%im0(g),1:this%jm0(g))=0.
+ H(1:this%km,1:this%im0(g+1),1:this%jm0(g+1))=H_INT(1:this%km,1:this%im0(g+1),1:this%jm0(g+1))
+ H_INT(1:this%km,-1:this%im0(g+1)+2,-1:this%jm0(g+1)+2)=0.
+ end do
+
+!-----------------------------------------------------------------------
+endsubroutine upsending_highest
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsending_highest &
+!***********************************************************************
+! !
+! Downsend, interpolate and add: !
+! First from gm->g3...->g2 !
+! Then from g2->g1 !
+! !
+!***********************************************************************
+(this,H,V)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(this%km,-1:this%imL+2,-1:this%jmL+2):: H_INT
+integer(i_kind):: g
+!-----------------------------------------------------------------------
+!
+! Upper generations
+!
+ do g=this%gm,2,-1
+ H_INT(1:this%km,-1:this%im0(g)+2,-1:this%jm0(g)+2)=0.
+ H_INT(1:this%km,1:this%im0(g),1:this%jm0(g))=H(1:this%km,1:this%im0(g),1:this%jm0(g))
+ H(1:this%km,1:this%im0(g-1),1:this%jm0(g-1))=0.
+ call this%direct_highest(H_INT(1:this%km,-1:this%im0(g)+2,-1:this%jm0(g)+2),&
+ & H(1:this%km,1:this%im0(g-1),1:this%jm0(g-1)),this%km,g-1)
+ enddo
+ V(:,:,:)=0.
+ V(1:this%km,1:this%im0(1),1:this%jm0(1))=H(1:this%km,1:this%im0(1),1:this%jm0(1))
+ H(:,:,:)=0.
+
+!-----------------------------------------------------------------------
+endsubroutine downsending_highest
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsending2 &
+!***********************************************************************
+! !
+! Adjoint interpolate and upsend: !
+! First from g1->g2 (V -> H) !
+! Then from g2->...->gn (H -> H) !
+! !
+!***********************************************************************
+(this,V,H)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+real(r_kind),dimension(this%km,0:this%imL+1,0:this%jmL+1):: V_INT
+real(r_kind),dimension(this%km,0:this%imL+1,0:this%jmL+1):: H_INT
+integer(i_kind):: g,L
+!-----------------------------------------------------------------------
+!
+! From generation 1 to generation 2
+!
+
+ call this%adjoint2(V(1:this%km,1:this%im,1:this%jm),V_INT,this%km,1)
+
+ call this%bocoT_2d(V_INT,this%km,this%imL,this%jmL,1,1)
+
+ call this%upsend_all(V_INT(1:this%km,1:this%imL,1:this%jmL),H,this%km)
+!
+! From generation 2 sequentially to higher generations
+!
+ do g=2,this%gm-1
+
+ if(g==this%my_hgen) then
+ call this%adjoint2(H(1:this%km,1:this%im,1:this%jm),H_INT,this%km,g)
+ endif
+
+ call this%bocoT_2d(H_INT,this%km,this%imL,this%jmL,1,1,this%FimaxL,this%FjmaxL,g,g)
+
+ call this%upsend_all(H_INT(1:this%km,1:this%imL,1:this%jmL),H,this%km,g,g+1)
+
+ end do
+
+!-----------------------------------------------------------------------
+endsubroutine upsending2
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsending2 &
+!***********************************************************************
+! !
+! Downsend, interpolate and add: !
+! First from gm->g3...->g2 !
+! Then from g2->g1 !
+! !
+!***********************************************************************
+(this,H,V)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(this%km,0:this%imL+1,0:this%jmL+1):: H_INT
+real(r_kind),dimension(this%km,0:this%imL+1,0:this%jmL+1):: V_INT
+real(r_kind),dimension(this%km,1:this%im,1:this%jm):: H_PROX
+real(r_kind),dimension(this%km,1:this%im,1:this%jm):: V_PROX
+integer(i_kind):: g,l,k
+integer(i_kind):: iL,jL,i,j
+!-----------------------------------------------------------------------
+!
+! Upper generations
+!
+ do g=this%gm,3,-1
+
+ call this%downsend_all(H(1:this%km,1:this%im,1:this%jm),H_INT(1:this%km,1:this%imL,1:this%jmL),this%km,g,g-1)
+ call this%boco_2d(H_INT,this%km,this%imL,this%jmL,1,1,this%FimaxL,this%FjmaxL,g-1,g-1)
+
+ if(this%my_hgen==g-1) then
+ call this%direct2(H_INT,H_PROX,this%km,g-1)
+ H(1:this%km,1:this%im,1:this%jm)=H (1:this%km,1:this%im,1:this%jm) &
+ +H_PROX(1:this%km,1:this%im,1:this%jm)
+ endif
+
+ enddo
+
+!
+! From generation 2 to generation 1
+!
+
+ call this%downsend_all(H(1:this%km,1:this%im,1:this%jm),V_INT(1:this%km,1:this%imL,1:this%jmL),this%km)
+ H(:,:,:)=0.
+
+ call this%boco_2d(V_INT,this%km,this%imL,this%jmL,1,1)
+
+ call this%direct2(V_INT,V_PROX,this%km,1)
+
+ V(1:this%km,1:this%im,1:this%jm)=V (1:this%km,1:this%im,1:this%jm) &
+ +V_PROX(1:this%km,1:this%im,1:this%jm)
+
+!-----------------------------------------------------------------------
+endsubroutine downsending2
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsending_ens &
+!***********************************************************************
+! !
+! Adjoint interpolate and upsend: !
+! First from g1->g2 (V -> H) !
+! Then from g2->...->gn (H -> H) !
+! !
+!***********************************************************************
+(this,V,H,kmx)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind), intent(in):: kmx
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+real(r_kind),dimension(kmx,-1:this%imL+2,-1:this%jmL+2):: V_INT
+real(r_kind),dimension(kmx,-1:this%imL+2,-1:this%jmL+2):: H_INT
+integer(i_kind):: g,L
+!-----------------------------------------------------------------------
+!
+! From generation 1 to generation 2
+!
+
+ call this%adjoint(V(1:kmx,1:this%im,1:this%jm),V_INT,kmx,1)
+
+ call this%bocoT_2d(V_INT,kmx,this%imL,this%jmL,2,2)
+
+ call this%upsend_all(V_INT(1:kmx,1:this%imL,1:this%jmL),H,kmx)
+!
+! From generation 2 sequentially to higher generations
+!
+ do g=2,this%gm-1
+
+ if(g==this%my_hgen) then
+ call this%adjoint(H(1:kmx,1:this%im,1:this%jm),H_INT,kmx,g)
+ endif
+
+ call this%bocoT_2d(H_INT,kmx,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,g,g)
+
+ call this%upsend_all(H_INT(1:kmx,1:this%imL,1:this%jmL),H,kmx,g,g+1)
+
+ end do
+
+!-----------------------------------------------------------------------
+endsubroutine upsending_ens
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsending_ens &
+!***********************************************************************
+! !
+! Downsend, interpolate and add: !
+! First from gm->g3...->g2 !
+! Then from g2->g1 !
+! !
+!***********************************************************************
+(this,H,V,kmx)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind), intent(in):: kmx
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(kmx,-1:this%imL+2,-1:this%jmL+2):: H_INT
+real(r_kind),dimension(kmx,-1:this%imL+2,-1:this%jmL+2):: V_INT
+real(r_kind),dimension(kmx,1:this%im,1:this%jm):: H_PROX
+real(r_kind),dimension(kmx,1:this%im,1:this%jm):: V_PROX
+integer(i_kind):: g,l,k
+integer(i_kind):: iL,jL,i,j
+!-----------------------------------------------------------------------
+!
+! Upper generations
+!
+ do g=this%gm,3,-1
+
+ call this%downsend_all(H(1:kmx,1:this%im,1:this%jm),H_INT(1:kmx,1:this%imL,1:this%jmL),kmx,g,g-1)
+
+ call this%boco_2d(H_INT,kmx,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,g-1,g-1)
+
+ if(this%my_hgen==g-1) then
+ call this%direct1(H_INT,H_PROX,kmx,g-1)
+ H(1:kmx,1:this%im,1:this%jm)=H (1:kmx,1:this%im,1:this%jm) &
+ +H_PROX(1:kmx,1:this%im,1:this%jm)
+ endif
+
+ enddo
+
+!
+! From geneartion 2 to generation 1
+!
+
+ call this%downsend_all(H(1:kmx,1:this%im,1:this%jm),V_INT(1:kmx,1:this%imL,1:this%jmL),kmx)
+ H(:,:,:)=0.
+
+ call this%boco_2d(V_INT,kmx,this%imL,this%jmL,2,2)
+
+ call this%direct1(V_INT,V_PROX,kmx,1)
+
+ V(1:kmx,1:this%im,1:this%jm)=V (1:kmx,1:this%im,1:this%jm) &
+ +V_PROX(1:kmx,1:this%im,1:this%jm)
+
+!-----------------------------------------------------------------------
+endsubroutine downsending_ens
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsending_ens_nearest &
+!***********************************************************************
+! !
+! Adjoint interpolate and upsend: !
+! First from g1->g2 (V -> H) !
+! Then from g2->...->gn (H -> H) !
+! !
+!***********************************************************************
+(this,V,H,kmx)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind), intent(in):: kmx
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+real(r_kind),dimension(kmx,-1:this%imL+2,-1:this%jmL+2):: V_INT
+real(r_kind),dimension(kmx,-1:this%imL+2,-1:this%jmL+2):: H_INT
+integer(i_kind):: g,L
+!-----------------------------------------------------------------------
+!
+! From generation 1 to generation 2
+!
+
+ call this%adjoint_nearest(V(1:kmx,1:this%im,1:this%jm),V_INT,kmx,1)
+
+ call this%bocoT_2d(V_INT,kmx,this%imL,this%jmL,2,2)
+
+ call this%upsend_all(V_INT(1:kmx,1:this%imL,1:this%jmL),H,kmx)
+!
+! From generation 2 sequentially to higher generations
+!
+ do g=2,this%gm-1
+
+ if(g==this%my_hgen) then
+ call this%adjoint_nearest(H(1:kmx,1:this%im,1:this%jm),H_INT,kmx,g)
+ endif
+
+ call this%bocoT_2d(H_INT,kmx,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,g,g)
+
+ call this%upsend_all(H_INT(1:kmx,1:this%imL,1:this%jmL),H,kmx,g,g+1)
+
+ end do
+
+!-----------------------------------------------------------------------
+endsubroutine upsending_ens_nearest
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsending_ens_nearest &
+!***********************************************************************
+! !
+! Downsend, interpolate and add: !
+! First from gm->g3...->g2 !
+! Then from g2->g1 !
+! !
+!***********************************************************************
+(this,H,V,kmx)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind), intent(in):: kmx
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(kmx,-1:this%imL+2,-1:this%jmL+2):: H_INT
+real(r_kind),dimension(kmx,-1:this%imL+2,-1:this%jmL+2):: V_INT
+real(r_kind),dimension(kmx,1:this%im,1:this%jm):: H_PROX
+real(r_kind),dimension(kmx,1:this%im,1:this%jm):: V_PROX
+integer(i_kind):: g,l,k
+integer(i_kind):: iL,jL,i,j
+!-----------------------------------------------------------------------
+!
+! Upper generations
+!
+ do g=this%gm,3,-1
+
+ call this%downsend_all(H(1:kmx,1:this%im,1:this%jm),H_INT(1:kmx,1:this%imL,1:this%jmL),kmx,g,g-1)
+
+ call this%boco_2d(H_INT,kmx,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,g-1,g-1)
+
+ if(this%my_hgen==g-1) then
+ call this%direct_nearest(H_INT,H_PROX,kmx,g-1)
+ H(1:kmx,1:this%im,1:this%jm)=H (1:kmx,1:this%im,1:this%jm) &
+ +H_PROX(1:kmx,1:this%im,1:this%jm)
+ endif
+
+ enddo
+
+!
+! From geneartion 2 to generation 1
+!
+
+ call this%downsend_all(H(1:kmx,1:this%im,1:this%jm),V_INT(1:kmx,1:this%imL,1:this%jmL),kmx)
+ H(:,:,:)=0.
+
+ call this%boco_2d(V_INT,kmx,this%imL,this%jmL,2,2)
+
+ call this%direct_nearest(V_INT,V_PROX,kmx,1)
+
+ V(1:kmx,1:this%im,1:this%jm)=V (1:kmx,1:this%im,1:this%jm) &
+ +V_PROX(1:kmx,1:this%im,1:this%jm)
+
+!-----------------------------------------------------------------------
+endsubroutine downsending_ens_nearest
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsending2_ens &
+!***********************************************************************
+! !
+! Adjoint interpolate and upsend: !
+! First from g1->g2 (V -> H) !
+! Then from g2->...->gn (H -> H) !
+! !
+!***********************************************************************
+(this,V,H,kmx)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind), intent(in):: kmx
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+real(r_kind),dimension(kmx,0:this%imL+1,0:this%jmL+1):: V_INT
+real(r_kind),dimension(kmx,0:this%imL+1,0:this%jmL+1):: H_INT
+integer(i_kind):: g,L
+!-----------------------------------------------------------------------
+!
+! From generation 1 to generation 2
+!
+
+ call this%adjoint2(V(1:kmx,1:this%im,1:this%jm),V_INT,kmx,1)
+
+ call this%bocoT_2d(V_INT,kmx,this%imL,this%jmL,1,1)
+
+ call this%upsend_all(V_INT(1:kmx,1:this%imL,1:this%jmL),H,kmx)
+!
+! From generation 2 sequentially to higher generations
+!
+ do g=2,this%gm-1
+
+ if(g==this%my_hgen) then
+ call this%adjoint2(H(1:kmx,1:this%im,1:this%jm),H_INT,kmx,g)
+ endif
+
+ call this%bocoT_2d(H_INT,kmx,this%imL,this%jmL,1,1,this%FimaxL,this%FjmaxL,g,g)
+
+ call this%upsend_all(H_INT(1:kmx,1:this%imL,1:this%jmL),H,kmx,g,g+1)
+
+ end do
+
+!-----------------------------------------------------------------------
+endsubroutine upsending2_ens
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsending2_ens &
+!***********************************************************************
+! !
+! Downsend, interpolate and add: !
+! First from gm->g3...->g2 !
+! Then from g2->g1 !
+! !
+!***********************************************************************
+(this,H,V,kmx)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind), intent(in):: kmx
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(kmx,0:this%imL+1,0:this%jmL+1):: H_INT
+real(r_kind),dimension(kmx,0:this%imL+1,0:this%jmL+1):: V_INT
+real(r_kind),dimension(kmx,1:this%im,1:this%jm):: H_PROX
+real(r_kind),dimension(kmx,1:this%im,1:this%jm):: V_PROX
+integer(i_kind):: g,l,k
+integer(i_kind):: iL,jL,i,j
+!-----------------------------------------------------------------------
+!
+! Upper generations
+!
+ do g=this%gm,3,-1
+
+ call this%downsend_all(H(1:kmx,1:this%im,1:this%jm),H_INT(1:kmx,1:this%imL,1:this%jmL),kmx,g,g-1)
+
+ call this%boco_2d(H_INT,kmx,this%imL,this%jmL,1,1,this%FimaxL,this%FjmaxL,g-1,g-1)
+
+ if(this%my_hgen==g-1) then
+ call this%direct2(H_INT,H_PROX,kmx,g-1)
+ H(1:kmx,1:this%im,1:this%jm)=H (1:kmx,1:this%im,1:this%jm) &
+ +H_PROX(1:kmx,1:this%im,1:this%jm)
+ endif
+
+ enddo
+
+!
+! From geneartion 2 to generation 1
+!
+
+ call this%downsend_all(H(1:kmx,1:this%im,1:this%jm),V_INT(1:kmx,1:this%imL,1:this%jmL),kmx)
+ H(:,:,:)=0.
+
+ call this%boco_2d(V_INT,kmx,this%imL,this%jmL,1,1)
+
+ call this%direct2(V_INT,V_PROX,kmx,1)
+
+ V(1:kmx,1:this%im,1:this%jm)=V (1:kmx,1:this%im,1:this%jm) &
+ +V_PROX(1:kmx,1:this%im,1:this%jm)
+
+!-----------------------------------------------------------------------
+endsubroutine downsending2_ens
+
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsending_loc_g3 &
+!***********************************************************************
+! !
+! Adjoint interpolate and upsend for localization: !
+! !
+! First from g1->g2: V(km ) -> H(km_4) !
+! Then from g2->g3: H(km_4 ) -> Z(km_16) !
+! !
+!***********************************************************************
+(this,V,H,Z,km_in,km_4_in,km_16_in)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: km_in,km_4_in,km_16_in
+real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: Z
+real(r_kind),dimension(km_in ,-1:this%imL+2,-1:this%jmL+2):: V_INT
+real(r_kind),dimension(km_4_in ,-1:this%imL+2,-1:this%jmL+2):: H_INT
+real(r_kind),dimension(km_16_in,-1:this%imL+2,-1:this%jmL+2):: Z_INT
+integer(i_kind):: g,L,ind,k_low,k_hgh
+!-----------------------------------------------------------------------
+!
+! From generation 1 to generation 2
+!
+
+ call this%adjoint(V(1:km_in,1:this%im,1:this%jm),V_INT,km_in,1)
+ call this%bocoT_2d(V_INT,km_in,this%imL,this%jmL,2,2) !?????
+
+ do ind=1,1
+ k_low=km_4_in*(ind-1)+1
+ k_hgh=km_4_in*ind
+ call this%upsend_loc_g12(V_INT(k_low:k_hgh,1:this%imL,1:this%jmL),H,km_4_in,ind)
+ enddo
+
+!
+! From generation 2 to generation 3
+!
+
+ call this%adjoint(H(1:km_4_in,1:this%im,1:this%jm),H_INT,km_4_in,2)
+ call this%bocoT_2d_loc(H_INT,km_4_in,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,2)
+
+ do ind=1,4
+ k_low=km_16_in*(ind-1)+1
+ k_hgh=km_16_in*ind
+ call this%upsend_loc_g23(H_INT(k_low:k_hgh,1:this%imL,1:this%jmL),Z,km_16_in,ind)
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine upsending_loc_g3
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine upsending_loc_g4 &
+!***********************************************************************
+! !
+! Adjoint interpolate and upsend for localization: !
+! !
+! First from g1->g2: V(km ) -> H(km_4) !
+! Then from g2->g3: H(km_4 ) -> Z(km_16) !
+! Then from g3->g4: Z(km_16) -> W(km_64) !
+! !
+!***********************************************************************
+(this,V,H,Z,W,km_in,km_4_in,km_16_in,km_64_in)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: km_in,km_4_in,km_16_in,km_64_in
+real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: Z
+real(r_kind),dimension(km_64_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: W
+real(r_kind),dimension(km_in ,-1:this%imL+2,-1:this%jmL+2):: V_INT
+real(r_kind),dimension(km_4_in ,-1:this%imL+2,-1:this%jmL+2):: H_INT
+real(r_kind),dimension(km_16_in,-1:this%imL+2,-1:this%jmL+2):: Z_INT
+real(r_kind),dimension(km_64_in,-1:this%imL+2,-1:this%jmL+2):: W_INT
+integer(i_kind):: g,L,ind,k_low,k_hgh
+!-----------------------------------------------------------------------
+!
+! From generation 1 to generation 2
+!
+
+ call this%adjoint(V(1:km_in,1:this%im,1:this%jm),V_INT,km_in,1)
+ call this%bocoT_2d(V_INT,km_in,this%imL,this%jmL,2,2) !?????
+
+ do ind=1,4
+ k_low=km_4_in*(ind-1)+1
+ k_hgh=km_4_in*ind
+ call this%upsend_loc_g12(V_INT(k_low:k_hgh,1:this%imL,1:this%jmL),H,km_4_in,ind)
+ enddo
+
+!
+! From generation 2 to generation 3
+!
+
+ call this%adjoint(H(1:km_4_in,1:this%im,1:this%jm),H_INT,km_4_in,2)
+ call this%bocoT_2d_loc(H_INT,km_4_in,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,2)
+
+ do ind=1,4
+ k_low=km_16_in*(ind-1)+1
+ k_hgh=km_16_in*ind
+ call this%upsend_loc_g23(H_INT(k_low:k_hgh,1:this%imL,1:this%jmL),Z,km_16_in,ind)
+ enddo
+
+!
+! From generation 3 to generation 4
+!
+
+ call this%adjoint(Z(1:km_16_in,1:this%im,1:this%jm),Z_INT,km_16_in,3)
+ call this%bocoT_2d_loc(H_INT,km_4_in,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,3)
+
+ do ind=1,4
+ k_low=km_64_in*(ind-1)+1
+ k_hgh=km_64_in*ind
+ call this%upsend_loc_g34(Z_INT(k_low:k_hgh,1:this%imL,1:this%jmL),W,km_64_in,ind)
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine upsending_loc_g4
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsending_loc_g3 &
+!***********************************************************************
+! !
+! Downsend, interpolate and add for localization: !
+! !
+! Then from g3->g2: Z(km_16) -> H(km_4 ) !
+! Then from g2->g1: H(km_4 ) -> V(km ) !
+! !
+!***********************************************************************
+(this,Z,H,V,km_in,km_4_in,km_16_in)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: km_in,km_4_in,km_16_in
+real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: Z
+real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(km_16_in,-1:this%imL+2,-1:this%jmL+2):: Z_INT
+real(r_kind),dimension(km_4_in ,-1:this%imL+2,-1:this%jmL+2):: H_INT
+real(r_kind),dimension(km_in ,-1:this%imL+2,-1:this%jmL+2):: V_INT
+real(r_kind),dimension(km_16_in,1:this%im,1:this%jm):: Z_PROX
+real(r_kind),dimension(km_4_in ,1:this%im,1:this%jm):: H_PROX
+real(r_kind),dimension(km_in ,1:this%im,1:this%jm):: V_PROX
+integer(i_kind):: g,l,k
+integer(i_kind):: iL,jL,i,j,ind,k_low,k_hgh
+!-----------------------------------------------------------------------
+!
+! From generation 3 to generation 2
+!
+ do ind=1,4
+ k_low=km_16_in*(ind-1)+1
+ k_hgh=km_16_in*ind
+ call this%downsend_loc_g32(Z(1:km_16_in,1:this%im,1:this%jm),H_INT(k_low:k_hgh,1:this%imL,1:this%jmL),km_16_in,ind)
+ enddo
+ Z(:,:,:)=0.
+
+ call this%boco_2d_loc(H_INT,km_4_in ,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,2)
+ call this%direct1(H_INT,H_PROX,km_4_in,2)
+
+ H(1:km_4_in ,1:this%im,1:this%jm)=H (1:km_4_in ,1:this%im,1:this%jm) &
+ +H_PROX(1:km_4_in ,1:this%im,1:this%jm)
+
+!
+! From geneartion 2 to generation 1
+!
+ do ind=1,4
+ k_low=km_4_in*(ind-1)+1
+ k_hgh=km_4_in*ind
+ call this%downsend_loc_g21(H(1:km_4_in,1:this%im,1:this%jm),V_INT(k_low:k_hgh,1:this%imL,1:this%jmL),km_4_in,ind)
+ enddo
+ H(:,:,:)=0.
+
+ call this%boco_2d(V_INT,km_in,this%imL,this%jmL,2,2)
+ call this%direct1(V_INT,V_PROX,km_in,1)
+
+ V(1:km_in,1:this%im,1:this%jm)=V (1:km_in,1:this%im,1:this%jm) &
+ +V_PROX(1:km_in,1:this%im,1:this%jm)
+
+!-----------------------------------------------------------------------
+endsubroutine downsending_loc_g3
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine downsending_loc_g4 &
+!***********************************************************************
+! !
+! Downsend, interpolate and add for localization: !
+! !
+! First from g4->g3: W(km_16) -> Z(km_64) !
+! Then from g3->g2: Z(km_16) -> H(km_4 ) !
+! Then from g2->g1: H(km_4 ) -> V(km ) !
+! !
+!***********************************************************************
+(this,W,Z,H,V,km_in,km_4_in,km_16_in,km_64_in)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: km_in,km_4_in,km_16_in,km_64_in
+real(r_kind),dimension(km_64_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: W
+real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: Z
+real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(km_64_in,-1:this%imL+2,-1:this%jmL+2):: W_INT
+real(r_kind),dimension(km_16_in,-1:this%imL+2,-1:this%jmL+2):: Z_INT
+real(r_kind),dimension(km_4_in ,-1:this%imL+2,-1:this%jmL+2):: H_INT
+real(r_kind),dimension(km_in ,-1:this%imL+2,-1:this%jmL+2):: V_INT
+real(r_kind),dimension(km_16_in,1:this%im,1:this%jm):: Z_PROX
+real(r_kind),dimension(km_4_in ,1:this%im,1:this%jm):: H_PROX
+real(r_kind),dimension(km_in ,1:this%im,1:this%jm):: V_PROX
+integer(i_kind):: g,l,k
+integer(i_kind):: iL,jL,i,j,ind,k_low,k_hgh
+!-----------------------------------------------------------------------
+!
+! From generation 4 to generation 3
+!
+ do ind=1,4
+ k_low=km_64_in*(ind-1)+1
+ k_hgh=km_64_in*ind
+ call this%downsend_loc_g43(W(1:km_64_in,1:this%im,1:this%jm),Z_INT(k_low:k_hgh,1:this%imL,1:this%jmL),km_64_in,ind)
+ enddo
+ W(:,:,:)=0.
+
+ call this%boco_2d_loc(Z_INT,km_16_in,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,3)
+ call this%direct1(Z_INT,Z_PROX,km_16_in,3)
+
+ Z(1:km_16_in,1:this%im,1:this%jm)=Z (1:km_16_in,1:this%im,1:this%jm) &
+ +Z_PROX(1:km_16_in,1:this%im,1:this%jm)
+
+!
+! From generation 3 to generation 2
+!
+ do ind=1,4
+ k_low=km_16_in*(ind-1)+1
+ k_hgh=km_16_in*ind
+ call this%downsend_loc_g32(Z(1:km_16_in,1:this%im,1:this%jm),H_INT(k_low:k_hgh,1:this%imL,1:this%jmL),km_16_in,ind)
+ enddo
+ Z(:,:,:)=0.
+
+ call this%boco_2d_loc(H_INT,km_4_in ,this%imL,this%jmL,2,2,this%FimaxL,this%FjmaxL,2)
+ call this%direct1(H_INT,H_PROX,km_4_in,2)
+
+ H(1:km_4_in ,1:this%im,1:this%jm)=H (1:km_4_in ,1:this%im,1:this%jm) &
+ +H_PROX(1:km_4_in ,1:this%im,1:this%jm)
+
+!
+! From geneartion 2 to generation 1
+!
+ do ind=1,4
+ k_low=km_4_in*(ind-1)+1
+ k_hgh=km_4_in*ind
+ call this%downsend_loc_g21(H(1:km_4_in,1:this%im,1:this%jm),V_INT(k_low:k_hgh,1:this%imL,1:this%jmL),km_4_in,ind)
+ enddo
+ H(:,:,:)=0.
+
+
+ call this%boco_2d(V_INT,km_in,this%imL,this%jmL,2,2)
+ call this%direct1(V_INT,V_PROX,km_in,1)
+
+ V(1:km_in,1:this%im,1:this%jm)=V (1:km_in,1:this%im,1:this%jm) &
+ +V_PROX(1:km_in,1:this%im,1:this%jm)
+
+!-----------------------------------------------------------------------
+endsubroutine downsending_loc_g4
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine weighting_helm &
+!***********************************************************************
+! !
+! Apply 2D differential operator to compound variable !
+! !
+!***********************************************************************
+(this,V,H)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+real(r_kind),dimension(this%km,0:this%im, 1:this%jm):: DIFX
+real(r_kind),dimension(this%km,1:this%im ,0:this%jm):: DIFY
+real(r_kind),dimension(this%km,0:this%im, 1:this%jm):: DIFXH
+real(r_kind),dimension(this%km,1:this%im ,0:this%jm):: DIFYH
+integer(i_kind):: i,j,l,k,imx,jmx
+!-----------------------------------------------------------------------
+
+ do j=1,this%jm
+ do i=0,this%im
+ DIFX(:,i,j)=V(:,i+1,j)-V(:,i,j)
+ enddo
+ enddo
+ do j=0,this%jm
+ do i=1,this%im
+ DIFY(:,i,j)=V(:,i,j+1)-V(:,i,j)
+ enddo
+ enddo
+
+ do j=1,this%jm
+ do i=1,this%im
+ V(:,i,j)=this%a_diff_f(:,i,j)*V(:,i,j) &
+ -this%b_diff_f(:,i,j)*(DIFX(:,i,j)-DIFX(:,i-1,j) &
+ +DIFY(:,i,j)-DIFY(:,i,j-1))
+ enddo
+ enddo
+
+if(this%l_hgen) then
+
+! imx = Fimax(my_hgen)
+! jmx = Fjmax(my_hgen)
+
+ imx = this%im
+ jmx = this%jm
+
+ do j=1,jmx
+ do i=0,imx
+ DIFXH(:,i,j)=H(:,i+1,j)-H(:,i,j)
+ enddo
+ enddo
+ do j=0,jmx
+ do i=1,imx
+ DIFYH(:,i,j)=H(:,i,j+1)-H(:,i,j)
+ enddo
+ enddo
+
+ do j=1,jmx
+ do i=1,imx
+ H(:,i,j)=this%a_diff_h(:,i,j)*H(:,i,j) &
+ -this%b_diff_h(:,i,j)*(DIFXH(:,i,j)-DIFXH(:,i-1,j) &
+ +DIFYH(:,i,j)-DIFYH(:,i,j-1))
+ enddo
+ enddo
+
+endif
+
+!-----------------------------------------------------------------------
+endsubroutine weighting_helm
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine weighting &
+!***********************************************************************
+! !
+! Apply 2D differential operator to compound variable !
+! !
+!***********************************************************************
+(this,V,H)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+integer(i_kind):: i,j,l,k,imx,jmx
+!-----------------------------------------------------------------------
+
+ do j=1,this%jm
+ do i=1,this%im
+ V(:,i,j)=this%a_diff_f(:,i,j)*V(:,i,j)
+ enddo
+ enddo
+
+if(this%l_hgen) then
+
+ imx = this%im
+ jmx = this%jm
+
+ do j=1,jmx
+ do i=1,imx
+ H(:,i,j)=this%a_diff_h(:,i,j)*H(:,i,j)
+ enddo
+ enddo
+
+endif
+
+!-----------------------------------------------------------------------
+endsubroutine weighting
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine weighting_highest &
+!***********************************************************************
+! !
+! Apply 2D differential operator to compound variable !
+! !
+!***********************************************************************
+(this,H)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+real(r_kind),dimension(this%km,1-this%hx:this%imH+this%hx,1-this%hy:this%jmH+this%hy),intent(inout):: H
+integer(i_kind):: i,j,imx,jmx
+!-----------------------------------------------------------------------
+
+ imx = this%imH
+ jmx = this%jmH
+
+ do j=1,jmx
+ do i=1,imx
+ H(:,i,j)=this%a_diff_h(:,i,j)*H(:,i,j)
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine weighting_highest
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine weighting_ens &
+!***********************************************************************
+! !
+! Apply 2D differential operator to compound variable for ensemble !
+! !
+!***********************************************************************
+(this,V,H,kmx)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: kmx
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+integer(i_kind):: i,j,l,k,imx,jmx
+!-----------------------------------------------------------------------
+
+if(this%l_filt_g1) then
+ do j=1,this%jm
+ do i=1,this%im
+ V(:,i,j)=this%a_diff_f(:,i,j)*V(:,i,j)
+ enddo
+ enddo
+else
+ V(:,:,:)=0.
+endif
+
+if(this%l_hgen) then
+
+ imx = this%im
+ jmx = this%jm
+
+ do j=1,jmx
+ do i=1,imx
+ H(:,i,j)=this%a_diff_h(:,i,j)*H(:,i,j)
+ enddo
+ enddo
+
+endif
+
+!-----------------------------------------------------------------------
+endsubroutine weighting_ens
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine weighting_loc_g3 &
+!***********************************************************************
+! !
+! Apply 2D differential operator to compound variable in the case !
+! of localization !
+! !
+!***********************************************************************
+(this,V,H04,H16,km_in,km_4_in,km_16_in)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind), intent(in):: km_in,km_4_in,km_16_in
+real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H04
+real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H16
+integer(i_kind):: i,j,l,k
+!-----------------------------------------------------------------------
+
+ do j=1,this%jm
+ do i=1,this%im
+ V (1:km_in ,i,j)=this%w1_loc(1:km_in ,i,j)*V (1:km_in ,i,j)
+ H04(1:km_4_in ,i,j)=this%w2_loc(1:km_4_in ,i,j)*H04(1:km_4_in ,i,j)
+ H16(1:km_16_in,i,j)=this%w3_loc(1:km_16_in,i,j)*H16(1:km_16_in,i,j)
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine weighting_loc_g3
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine weighting_loc_g4 &
+!***********************************************************************
+! !
+! Apply 2D differential operator to compound variable in the case !
+! of localization !
+! !
+!***********************************************************************
+(this,V,H04,H16,H64,km_in,km_4_in,km_16_in,km_64_in)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind), intent(in):: km_in,km_4_in,km_16_in,km_64_in
+real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H04
+real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H16
+real(r_kind),dimension(km_64_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H64
+integer(i_kind):: i,j,l,k
+!-----------------------------------------------------------------------
+
+ do j=1,this%jm
+ do i=1,this%im
+ V (1:km_in ,i,j)=this%w1_loc(1:km_in ,i,j)*V (1:km_in ,i,j)
+ H04(1:km_4_in ,i,j)=this%w2_loc(1:km_4_in ,i,j)*H04(1:km_4_in ,i,j)
+ H16(1:km_16_in,i,j)=this%w3_loc(1:km_16_in,i,j)*H16(1:km_16_in,i,j)
+ H64(1:km_64_in,i,j)=this%w4_loc(1:km_64_in,i,j)*H64(1:km_64_in,i,j)
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine weighting_loc_g4
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine adjoint &
+!***********************************************************************
+! !
+! Mapping from the high to low resolution grid !
+! using linearly squared interpolations !
+! - offset version - !
+! !
+!***********************************************************************
+(this,F,W,km_in,g)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: g
+integer(i_kind),intent(in):: km_in
+real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(in):: F
+real(r_kind), dimension(km_in,-1:this%imL+2,-1:this%jmL+2), intent(out):: W
+real(r_kind), dimension(km_in,1:this%im,-1:this%jmL+2):: W_AUX
+integer(i_kind):: i,j,iL,jL
+!-----------------------------------------------------------------------
+!
+! 3)
+!
+ W_AUX(:,:,:)= 0.
+
+ do j=this%jm-mod(this%jm,2),2,-2
+ jL = j/2
+ do i=this%im,1,-1
+ W_AUX(:,i,jL+2)=W_AUX(:,i,jL+2)+this%p_coef(4)*F(:,i,j)
+ W_AUX(:,i,jL+1)=W_AUX(:,i,jL+1)+this%p_coef(3)*F(:,i,j)
+ W_AUX(:,i,jL )=W_AUX(:,i,jL )+this%p_coef(2)*F(:,i,j)
+ W_AUX(:,i,jL-1)=W_AUX(:,i,jL-1)+this%p_coef(1)*F(:,i,j)
+ enddo
+ enddo
+!
+! 2)
+!
+ do j=this%jm-1+mod(this%jm,2),1,-2
+ jL=j/2
+ do i=this%im,1,-1
+ W_AUX(:,i,jL+2)=W_AUX(:,i,jL+2)+this%q_coef(4)*F(:,i,j)
+ W_AUX(:,i,jL+1)=W_AUX(:,i,jL+1)+this%q_coef(3)*F(:,i,j)
+ W_AUX(:,i,jL )=W_AUX(:,i,jL )+this%q_coef(2)*F(:,i,j)
+ W_AUX(:,i,jL-1)=W_AUX(:,i,jL-1)+this%q_coef(1)*F(:,i,j)
+ enddo
+ enddo
+
+ W(:,:,:)=0.
+!
+! 1)
+!
+ do jL=this%jmL+2,-1,-1
+ do i=this%im-1+mod(this%im,2),1,-2
+ iL = i/2
+ W(:,iL+2,jL)=W(:,iL+2,jL)+this%q_coef(4)*W_AUX(:,i,jL)
+ W(:,iL+1,jL)=W(:,iL+1,jL)+this%q_coef(3)*W_AUX(:,i,jL)
+ W(:,iL ,jL)=W(:,iL ,jL)+this%q_coef(2)*W_AUX(:,i,jL)
+ W(:,iL-1,jL)=W(:,iL-1,jL)+this%q_coef(1)*W_AUX(:,i,jL)
+ enddo
+ do i=this%im-mod(this%im,2),2,-2
+ iL=i/2
+ W(:,iL+2,jL)=W(:,iL+2,jL)+this%p_coef(4)*W_AUX(:,i,jL)
+ W(:,iL+1,jL)=W(:,iL+1,jL)+this%p_coef(3)*W_AUX(:,i,jL)
+ W(:,iL ,jL)=W(:,iL ,jL)+this%p_coef(2)*W_AUX(:,i,jL)
+ W(:,iL-1,jL)=W(:,iL-1,jL)+this%p_coef(1)*W_AUX(:,i,jL)
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine adjoint
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine direct1 &
+!***********************************************************************
+! !
+! Mapping from the low to high resolution grid !
+! using linearly squared interpolations !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,F,km_in,g)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: g
+integer(i_kind),intent(in):: km_in
+real(r_kind), dimension(km_in,-1:this%imL+2,-1:this%jmL+2), intent(in):: W
+real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(out):: F
+real(r_kind), dimension(km_in,1:this%im,-1:this%jmL+2):: W_AUX
+integer(i_kind):: i,j,iL,jL
+!-----------------------------------------------------------------------
+!
+! 1)
+!
+ do jL=-1,this%jmL+2
+ do i=1,this%im-1+mod(this%im,2),2
+ iL=i/2
+ W_AUX(:,i,jL)=this%q_coef(1)*W(:,iL-1,jL)+this%q_coef(2)*W(:,iL ,jL) &
+ +this%q_coef(3)*W(:,iL+1,jL)+this%q_coef(4)*W(:,iL+2,jL)
+ enddo
+ do i=2,this%im-mod(this%im,2),2
+ iL=i/2
+ W_AUX(:,i,jL)=this%p_coef(1)*W(:,iL-1,jL)+this%p_coef(2)*w(:,iL ,jL) &
+ +this%p_coef(3)*W(:,iL+1,jL)+this%p_coef(4)*W(:,iL+2,jL)
+ enddo
+ enddo
+!
+! 2)
+!
+ do j=1,this%jm-1+mod(this%jm,2),2
+ jL=j/2
+ do i=1,this%im
+ F(:,i,j)=this%q_coef(1)*W_AUX(:,i,jL-1)+this%q_coef(2)*W_AUX(:,i,jL ) &
+ +this%q_coef(3)*W_AUX(:,i,jL+1)+this%q_coef(4)*W_AUX(:,i,jL+2)
+ enddo
+ enddo
+!
+! 3)
+!
+ do j=2,this%jm-mod(this%jm,2),2
+ jL=j/2
+ do i=1,this%im
+ F(:,i,j)=this%p_coef(1)*W_AUX(:,i,jL-1)+this%p_coef(2)*W_AUX(:,i,jL ) &
+ +this%p_coef(3)*W_AUX(:,i,jL+1)+this%p_coef(4)*W_AUX(:,i,jL+2)
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine direct1
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine adjoint2 &
+!***********************************************************************
+! !
+! Mapping from the high to low resolution grid !
+! using quadratics interpolations !
+! - offset version - !
+! !
+!***********************************************************************
+(this,F,W,km_in,g)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: g
+integer(i_kind),intent(in):: km_in
+real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(in):: F
+real(r_kind), dimension(km_in,0:this%imL+1,0:this%jmL+1), intent(out):: W
+real(r_kind), dimension(km_in,1:this%im,0:this%jmL+1):: W_AUX
+integer(i_kind):: i,j,iL,jL
+!-----------------------------------------------------------------------
+!
+! 3)
+!
+ W_AUX(:,:,:)= 0.
+
+ do j=this%jm-mod(this%jm,2),2,-2
+ jL = j/2
+ do i=this%im,1,-1
+ W_AUX(:,i,jL+1)=W_AUX(:,i,jL+1)+this%b_coef(3)*F(:,i,j)
+ W_AUX(:,i,jL )=W_AUX(:,i,jL )+this%b_coef(2)*F(:,i,j)
+ W_AUX(:,i,jL-1)=W_AUX(:,i,jL-1)+this%b_coef(1)*F(:,i,j)
+ enddo
+ enddo
+!
+! 2)
+!
+ do j=this%jm-1+mod(this%jm,2),1,-2
+ jL=(j+1)/2
+ do i=this%im,1,-1
+ W_AUX(:,i,jL+1)=W_AUX(:,i,jL+1)+this%a_coef(3)*F(:,i,j)
+ W_AUX(:,i,jL )=W_AUX(:,i,jL )+this%a_coef(2)*F(:,i,j)
+ W_AUX(:,i,jL-1)=W_AUX(:,i,jL-1)+this%a_coef(1)*F(:,i,j)
+ enddo
+ enddo
+
+ W(:,:,:)=0.
+!
+! 1)
+!
+ do jL=this%jmL+1,0,-1
+ do i=this%im-1+mod(this%im,2),1,-2
+ iL = (i+1)/2
+ W(:,iL+1,jL)=W(:,iL+1,jL)+this%a_coef(3)*W_AUX(:,i,jL)
+ W(:,iL ,jL)=W(:,iL ,jL)+this%a_coef(2)*W_AUX(:,i,jL)
+ W(:,iL-1,jL)=W(:,iL-1,jL)+this%a_coef(1)*W_AUX(:,i,jL)
+ enddo
+ do i=this%im-mod(this%im,2),2,-2
+ iL=i/2
+ W(:,iL+1,jL)=W(:,iL+1,jL)+this%b_coef(3)*W_AUX(:,i,jL)
+ W(:,iL ,jL)=W(:,iL ,jL)+this%b_coef(2)*W_AUX(:,i,jL)
+ W(:,iL-1,jL)=W(:,iL-1,jL)+this%b_coef(1)*W_AUX(:,i,jL)
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine adjoint2
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine direct2 &
+!***********************************************************************
+! !
+! Mapping from the low to high resolution grid !
+! using quadratic interpolations !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,F,km_in,g)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: g
+integer(i_kind),intent(in):: km_in
+real(r_kind), dimension(km_in,0:this%imL+1,0:this%jmL+1), intent(in):: W
+real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(out):: F
+real(r_kind), dimension(km_in,1:this%im,0:this%jmL+1):: W_AUX
+integer(i_kind):: i,j,iL,jL
+!-----------------------------------------------------------------------
+!
+! 1)
+!
+ do jL=0,this%jmL+1
+ do i=1,this%im-1+mod(this%im,2),2
+ iL=(i+1)/2
+ W_AUX(:,i,jL)=this%a_coef(1)*W(:,iL-1,jL)+this%a_coef(2)*W(:,iL ,jL) &
+ +this%a_coef(3)*W(:,iL+1,jL)
+ enddo
+ do i=2,this%im-mod(this%im,2),2
+ iL=i/2
+ W_AUX(:,i,jL)=this%b_coef(1)*W(:,iL-1,jL)+this%b_coef(2)*w(:,iL ,jL) &
+ +this%b_coef(3)*W(:,iL+1,jL)
+ enddo
+ enddo
+!
+! 2)
+!
+ do j=1,this%jm-1+mod(this%jm,2),2
+ jL=(j+1)/2
+ do i=1,this%im
+ F(:,i,j)=this%a_coef(1)*W_AUX(:,i,jL-1)+this%a_coef(2)*W_AUX(:,i,jL ) &
+ +this%a_coef(3)*W_AUX(:,i,jL+1)
+ enddo
+ enddo
+!
+! 3)
+!
+ do j=2,this%jm-mod(this%jm,2),2
+ jL=j/2
+ do i=1,this%im
+ F(:,i,j)=this%b_coef(1)*W_AUX(:,i,jL-1)+this%b_coef(2)*W_AUX(:,i,jL ) &
+ +this%b_coef(3)*W_AUX(:,i,jL+1)
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine direct2
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine adjoint_nearest &
+!***********************************************************************
+! !
+! Mapping from the high to low resolution grid !
+! selecting the nearest point !
+! - offset version - !
+! !
+!***********************************************************************
+(this,F,W,km_in,g)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: g
+integer(i_kind),intent(in):: km_in
+real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(in):: F
+real(r_kind), dimension(km_in,-1:this%imL+2,-1:this%jmL+2), intent(out):: W
+real(r_kind), dimension(km_in,1:this%im,-1:this%jmL+2):: W_AUX
+integer(i_kind):: i,j,iL,jL
+!-----------------------------------------------------------------------
+!
+! 3)
+!
+ W_AUX(:,:,:)= 0.
+
+ do j=this%jm-mod(this%jm,2),2,-2
+ jL = j/2
+ do i=this%im,1,-1
+ W_AUX(:,i,jL )=W_AUX(:,i,jL )+0.5**0.5*F(:,i,j)
+ enddo
+ enddo
+!
+! 2)
+!
+ do j=this%jm-1+mod(this%jm,2),1,-2
+ jL=j/2
+ do i=this%im,1,-1
+ W_AUX(:,i,jL+1)=W_AUX(:,i,jL+1)+0.5**0.5*F(:,i,j)
+ enddo
+ enddo
+
+ W(:,:,:)=0.
+!
+! 1)
+!
+ do jL=this%jmL+2,-1,-1
+ do i=this%im-1+mod(this%im,2),1,-2
+ iL = i/2
+ W(:,iL+1,jL)=W(:,iL+1,jL)+0.5**0.5*W_AUX(:,i,jL)
+ enddo
+ do i=this%im-mod(this%im,2),2,-2
+ iL=i/2
+ W(:,iL ,jL)=W(:,iL ,jL)+0.5**0.5*W_AUX(:,i,jL)
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine adjoint_nearest
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine direct_nearest &
+!***********************************************************************
+! !
+! Mapping from the low to high resolution grid !
+! selecting the nearest point !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,F,km_in,g)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: g
+integer(i_kind),intent(in):: km_in
+real(r_kind), dimension(km_in,-1:this%imL+2,-1:this%jmL+2), intent(in):: W
+real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(out):: F
+real(r_kind), dimension(km_in,1:this%im,-1:this%jmL+2):: W_AUX
+integer(i_kind):: i,j,iL,jL
+!-----------------------------------------------------------------------
+!
+! 1)
+!
+ do jL=-1,this%jmL+2
+ do i=1,this%im-1+mod(this%im,2),2
+ iL=i/2
+ W_AUX(:,i,jL)=0.5**0.5*W(:,iL+1,jL)
+ enddo
+ do i=2,this%im-mod(this%im,2),2
+ iL=i/2
+ W_AUX(:,i,jL)=0.5**0.5*w(:,iL ,jL)
+ enddo
+ enddo
+!
+! 2)
+!
+ do j=1,this%jm-1+mod(this%jm,2),2
+ jL=j/2
+ do i=1,this%im
+ F(:,i,j)=0.5**0.5*W_AUX(:,i,jL+1)
+ enddo
+ enddo
+!
+! 3)
+!
+ do j=2,this%jm-mod(this%jm,2),2
+ jL=j/2
+ do i=1,this%im
+ F(:,i,j)=0.5**0.5*W_AUX(:,i,jL )
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine direct_nearest
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine adjoint_highest &
+!***********************************************************************
+! !
+! Mapping from the high to low resolution grid !
+! using linearly squared interpolations !
+! - offset version - !
+! !
+!***********************************************************************
+(this,F,W,km_in,g)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: g
+integer(i_kind),intent(in):: km_in
+real(r_kind), dimension(km_in,1:this%im0(g),1:this%jm0(g)), intent(in):: F
+real(r_kind), dimension(km_in,-1:this%im0(g+1)+2,-1:this%jm0(g+1)+2), intent(out):: W
+real(r_kind), dimension(km_in,1:this%im0(g),-1:this%jm0(g+1)+2):: W_AUX
+integer(i_kind):: i,j,iL,jL
+!-----------------------------------------------------------------------
+!
+! 3)
+!
+ W_AUX(:,:,:)= 0.
+
+ do j=this%jm0(g)-mod(this%jm0(g),2),2,-2
+ jL = j/2
+ do i=this%im0(g),1,-1
+ W_AUX(:,i,jL+2)=W_AUX(:,i,jL+2)+this%p_coef(4)*F(:,i,j)
+ W_AUX(:,i,jL+1)=W_AUX(:,i,jL+1)+this%p_coef(3)*F(:,i,j)
+ W_AUX(:,i,jL )=W_AUX(:,i,jL )+this%p_coef(2)*F(:,i,j)
+ W_AUX(:,i,jL-1)=W_AUX(:,i,jL-1)+this%p_coef(1)*F(:,i,j)
+ enddo
+ enddo
+!
+! 2)
+!
+ do j=this%jm0(g)-1+mod(this%jm0(g),2),1,-2
+ jL=j/2
+ do i=this%im0(g),1,-1
+ W_AUX(:,i,jL+2)=W_AUX(:,i,jL+2)+this%q_coef(4)*F(:,i,j)
+ W_AUX(:,i,jL+1)=W_AUX(:,i,jL+1)+this%q_coef(3)*F(:,i,j)
+ W_AUX(:,i,jL )=W_AUX(:,i,jL )+this%q_coef(2)*F(:,i,j)
+ W_AUX(:,i,jL-1)=W_AUX(:,i,jL-1)+this%q_coef(1)*F(:,i,j)
+ enddo
+ enddo
+
+ W(:,:,:)=0.
+!
+! 1)
+!
+ do jL=this%jm0(g+1)+2,-1,-1
+ do i=this%im0(g)-1+mod(this%im0(g),2),1,-2
+ iL = i/2
+ W(:,iL+2,jL)=W(:,iL+2,jL)+this%q_coef(4)*W_AUX(:,i,jL)
+ W(:,iL+1,jL)=W(:,iL+1,jL)+this%q_coef(3)*W_AUX(:,i,jL)
+ W(:,iL ,jL)=W(:,iL ,jL)+this%q_coef(2)*W_AUX(:,i,jL)
+ W(:,iL-1,jL)=W(:,iL-1,jL)+this%q_coef(1)*W_AUX(:,i,jL)
+ enddo
+ do i=this%im0(g)-mod(this%im0(g),2),2,-2
+ iL=i/2
+ W(:,iL+2,jL)=W(:,iL+2,jL)+this%p_coef(4)*W_AUX(:,i,jL)
+ W(:,iL+1,jL)=W(:,iL+1,jL)+this%p_coef(3)*W_AUX(:,i,jL)
+ W(:,iL ,jL)=W(:,iL ,jL)+this%p_coef(2)*W_AUX(:,i,jL)
+ W(:,iL-1,jL)=W(:,iL-1,jL)+this%p_coef(1)*W_AUX(:,i,jL)
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine adjoint_highest
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine direct_highest &
+!***********************************************************************
+! !
+! Mapping from the low to high resolution grid !
+! using linearly squared interpolations !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,F,km_in,g)
+!-----------------------------------------------------------------------
+implicit none
+class (mg_intstate_type),target:: this
+integer(i_kind),intent(in):: g
+integer(i_kind),intent(in):: km_in
+real(r_kind), dimension(km_in,-1:this%im0(g+1)+2,-1:this%jm0(g+1)+2), intent(in):: W
+real(r_kind), dimension(km_in,1:this%im0(g),1:this%jm0(g)), intent(out):: F
+real(r_kind), dimension(km_in,1:this%im0(g),-1:this%jm0(g+1)+2):: W_AUX
+integer(i_kind):: i,j,iL,jL
+!-----------------------------------------------------------------------
+!
+! 1)
+!
+ do jL=-1,this%jm0(g+1)+2
+ do i=1,this%im0(g)-1+mod(this%im0(g),2),2
+ iL=i/2
+ W_AUX(:,i,jL)=this%q_coef(1)*W(:,iL-1,jL)+this%q_coef(2)*W(:,iL ,jL) &
+ +this%q_coef(3)*W(:,iL+1,jL)+this%q_coef(4)*W(:,iL+2,jL)
+ enddo
+ do i=2,this%im0(g)-mod(this%im0(g),2),2
+ iL=i/2
+ W_AUX(:,i,jL)=this%p_coef(1)*W(:,iL-1,jL)+this%p_coef(2)*w(:,iL ,jL) &
+ +this%p_coef(3)*W(:,iL+1,jL)+this%p_coef(4)*W(:,iL+2,jL)
+ enddo
+ enddo
+!
+! 2)
+!
+ do j=1,this%jm0(g)-1+mod(this%jm0(g),2),2
+ jL=j/2
+ do i=1,this%im0(g)
+ F(:,i,j)=this%q_coef(1)*W_AUX(:,i,jL-1)+this%q_coef(2)*W_AUX(:,i,jL ) &
+ +this%q_coef(3)*W_AUX(:,i,jL+1)+this%q_coef(4)*W_AUX(:,i,jL+2)
+ enddo
+ enddo
+!
+! 3)
+!
+ do j=2,this%jm0(g)-mod(this%jm0(g),2),2
+ jL=j/2
+ do i=1,this%im0(g)
+ F(:,i,j)=this%p_coef(1)*W_AUX(:,i,jL-1)+this%p_coef(2)*W_AUX(:,i,jL ) &
+ +this%p_coef(3)*W_AUX(:,i,jL+1)+this%p_coef(4)*W_AUX(:,i,jL+2)
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine direct_highest
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+end submodule mg_generations
diff --git a/src/mgbf/mg_input.f90 b/src/mgbf/mg_input.f90
new file mode 100644
index 0000000000..80b0772c12
--- /dev/null
+++ b/src/mgbf/mg_input.f90
@@ -0,0 +1,155 @@
+module mg_input
+!$$$ submodule documentation block
+! . . . .
+! module: mg_input
+! prgmmr: rancic org: NCEP/EMC date:
+!
+! abstract: Module for data input
+! (Here will be defined uniform decomposition and padding
+! with zeros of control variables, required by the filter)
+!
+! module history log:
+! 2023-04-19 lei - object-oriented coding
+! 2024-01-11 rancic - optimization for ensemble localization
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! input_2d -
+! input_spec1_2d -
+! input_3d -
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+
+use mg_intstate, only : mg_intstate_type
+public input_2d
+public input_spec1_2d
+public input_3d
+
+!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+contains
+!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+subroutine input_2d &
+!***********************************************************************
+! !
+! Define some function for testing redecomposition !
+! (for analysis grid) !
+! !
+!***********************************************************************
+(obj_intstate,V,imin,jmin,imax,jmax,imax0,ampl)
+!-----------------------------------------------------------------------
+use kinds, only: r_kind,i_kind
+implicit none
+class (mg_intstate_type):: obj_intstate
+integer(i_kind),intent(in):: imax,jmax
+integer(i_kind),intent(in):: imin,jmin
+integer(i_kind),intent(in):: imax0
+integer(i_kind),intent(in):: ampl
+real(r_kind),dimension(imin:imax,jmin:jmax),intent(out):: V
+real(i_kind):: ng,mg,L,m,n
+!-----------------------------------------------------------------------
+
+ do m=imin,jmax
+ mg = (obj_intstate%my-1)*jmax+m
+ do n=jmin,imax
+ ng = (obj_intstate%nx-1)*imax+n
+ V(n,m)=ampl*(mg*imax0+ng)
+! V(n,m)=0.
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine input_2d
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+subroutine input_spec1_2d &
+!***********************************************************************
+! !
+! Define some function for testing redecomposition !
+! (for analysis grid) !
+! !
+!***********************************************************************
+(obj_intstate,V,nx0,my0,flag)
+!-----------------------------------------------------------------------
+use kinds, only: r_kind,i_kind
+implicit none
+class (mg_intstate_type):: obj_intstate
+integer(i_kind),intent(in):: nx0,my0
+real(r_kind),dimension(1:obj_intstate%nm,1:obj_intstate%mm),intent(out):: V
+character(len=2), intent(in):: flag
+integer(r_kind):: v0=1.
+!-----------------------------------------------------------------------
+
+ V(:,:)=0.
+
+if(flag=='md') then
+ if(obj_intstate%nx==nx0.and.obj_intstate%my==my0) then
+ V(obj_intstate%nm/2,obj_intstate%mm/2)=v0
+ endif
+else &
+if(flag=='rt') then
+ if(obj_intstate%nx==nx0.and.obj_intstate%my==my0) then
+ V(obj_intstate%nm,obj_intstate%mm)=v0
+ endif
+ if(obj_intstate%nx==nx0+1.and.obj_intstate%my==my0) then
+ V(1,obj_intstate%mm)=v0
+ endif
+ if(obj_intstate%nx==nx0.and.obj_intstate%my==my0+1) then
+ V(obj_intstate%nm,1)=v0
+ endif
+ if(obj_intstate%nx==nx0+1.and.obj_intstate%my==my0+1) then
+ V(1,1)=v0
+ endif
+endif
+
+!-----------------------------------------------------------------------
+endsubroutine input_spec1_2d
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+subroutine input_3d &
+!***********************************************************************
+! !
+! Define some function for testing redecomposition !
+! (for analysis grid) !
+! !
+!***********************************************************************
+(obj_intstate,V,imin,jmin,lmin,imax,jmax,lmax,imax0,ampl,incrm)
+!-----------------------------------------------------------------------
+use kinds, only: r_kind,i_kind
+implicit none
+class (mg_intstate_type):: obj_intstate
+integer(i_kind),intent(in):: imin,jmin,lmin
+integer(i_kind),intent(in):: imax,jmax,lmax
+integer(i_kind),intent(in):: imax0
+integer(i_kind),intent(in):: ampl,incrm
+real(r_kind),dimension(lmin:lmax,imin:imax,jmin:jmax),intent(out):: V
+real(i_kind):: ng,mg,L,m,n
+!-----------------------------------------------------------------------
+
+ do l=lmin,lmax
+ do m=imin,jmax
+ mg = (obj_intstate%my-1)*jmax+m
+ do n=jmin,imax
+ ng = (obj_intstate%nx-1)*imax+n
+ V(l,n,m)=ampl*(mg*imax0+ng) +(l-1)*incrm
+! V(l,n,m)=0.
+ enddo
+ enddo
+ enddo
+
+!-----------------------------------------------------------------------
+endsubroutine input_3d
+
+!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+end module mg_input
diff --git a/src/mgbf/mg_interpolate.f90 b/src/mgbf/mg_interpolate.f90
new file mode 100644
index 0000000000..5346792581
--- /dev/null
+++ b/src/mgbf/mg_interpolate.f90
@@ -0,0 +1,972 @@
+submodule(mg_intstate) mg_interpolate
+!$$$ submodule documentation block
+! . . . .
+! module: mg_interpolate
+! prgmmr: rancic org: NCEP/EMC date: 2020
+!
+! abstract: General mapping between 2d arrays using linerly squared
+! interpolations
+!
+! module history log:
+! 2023-04-19 lei - object-oriented coding
+! 2024-01-11 rancic - optimization for ensemble localization
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! def_offset_coef -
+! lsqr_mg_coef -
+! lwq_vertical_coef -
+! lwq_vertical_adjoint -
+! lwq_vertical_direct -
+! lwq_vertical_adjoint_spec -
+! lwq_vertical_direct_spec -
+! l_vertical_adjoint_spec -
+! l_vertical_direct_spec -
+! lsqr_direct_offset -
+! lsqr_adjoint_offset -
+! quad_direct_offset -
+! quad_adjoint_offset -
+! lin_direct_offset -
+! lin_adjoint_offset -
+! l_vertical_adjoint_spec2 -
+! l_vertical_direct_spec2 -
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use kinds
+use jp_pkind2, only: fpi
+
+implicit none
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+contains
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine def_offset_coef (this)
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+
+real(r_kind):: r64,r32,r128
+!-----------------------------------------------------------------------
+ r64 = 1.0d0/64.0d0
+ r32 = 1.0d0/32.0d0
+ r128= 1.0d0/128.0d0
+
+! p_coef =(/-3.,51,29,-3/)
+! q_coef =(/-3.,19.0d0,51.0d0,-3.0d0/)
+! p_coef = p_coef*r64
+! q_coef = q_coef*r64
+
+ this%p_coef =(/-9.,111.,29.,-3./)
+ this%q_coef =(/-3.,29.,111.,-9./)
+ this%p_coef = this%p_coef*r128
+ this%q_coef = this%q_coef*r128
+
+ this%a_coef =(/5.,30.,-3./)
+ this%b_coef =(/-3.,30.,5./)
+ this%a_coef=this%a_coef*r32
+ this%b_coef=this%b_coef*r32
+!-----------------------------------------------------------------------
+endsubroutine def_offset_coef
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine lsqr_mg_coef (this)
+!***********************************************************************
+! !
+! Prepare coeficients for mapping between: !
+! filter grid on analysis decomposition: W(1-ib:im+ib,1-jb:jm+jb) !
+! and analysis grid: V(1:nm,1:mm) !
+! - offset version - !
+! !
+! ( im < nm and jm < mm ) !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+real(r_kind), dimension(1:this%nm):: xa
+real(r_kind), dimension(1-this%ib:this%im+this%ib):: xf
+real(r_kind), dimension(1:this%mm):: ya
+real(r_kind), dimension(1-this%jb:this%jm+this%jb):: yf
+integer(i_kind):: i,j,n,m
+real(r_kind) x1,x2,x3,x4,x
+real(r_kind) x1x,x2x,x3x,x4x
+real(r_kind) rx2x1,rx3x1,rx4x1,rx3x2,rx4x2,rx4x3
+real(r_kind) y1,y2,y3,y4,y
+real(r_kind) y1y,y2y,y3y,y4y
+real(r_kind) ry2y1,ry3y1,ry4y1,ry3y2,ry4y2,ry4y3
+real(r_kind) cfl1,cfl2,cfl3,cll
+real(r_kind) cfr1,cfr2,cfr3,crr
+real(r_kind) x1_x,x2_x,x3_x
+real(r_kind) y1_y,y2_y,y3_y
+!-----------------------------------------------------------------------
+!
+! Initialize
+!
+
+ do n=1,this%nm
+ xa(n)=this%xa0+this%dxa*(n-1)
+ enddo
+
+ do i=1-this%ib,this%im+this%ib
+ xf(i)=this%xf0+this%dxf*(i-1)
+ enddo
+
+ do m=1,this%mm
+ ya(m)=this%ya0+this%dya*(m-1)
+ enddo
+
+ do j=1-this%jb,this%jm+this%jb
+ yf(j)=this%yf0+this%dyf*(j-1)
+ enddo
+
+!
+! Find iref and jref
+!
+ do n=1,this%nm
+ do i=1-this%ib,this%im+this%ib-1
+ if( xa(n)< xf(i)) then
+ this%iref(n)=i-2
+ this%irefq(n)=i-1
+ this%irefL(n)=i-1
+ exit
+ endif
+ enddo
+ enddo
+
+ do m=1,this%mm
+ do j=1-this%jb,this%jm+this%jb-1
+ if(ya(m) < yf(j)) then
+ this%jref(m)=j-2
+ this%jrefq(m)=j-1
+ this%jrefL(m)=j-1
+ exit
+ endif
+ enddo
+ enddo
+
+ do n=1,this%nm
+ i=this%iref(n)
+ x1=xf(i)
+ x2=xf(i+1)
+ x3=xf(i+2)
+ x4=xf(i+3)
+ x = xa(n)
+ x1x = x1-x
+ x2x = x2-x
+ x3x = x3-x
+ x4x = x4-x
+ rx2x1 = 1./(x2-x1)
+ rx3x1 = 1./(x3-x1)
+ rx4x1 = 1./(x4-x1)
+ rx3x2 = 1./(x3-x2)
+ rx4x2 = 1./(x4-x2)
+ rx4x3 = 1./(x4-x3)
+ CFL1 = x2x*x3x*rx2x1*rx3x1
+ CFL2 =-x1x*x3x*rx2x1*rx3x2
+ CFL3 = x1x*x2x*rx3x1*rx3x2
+ CLL = x3x*rx3x2
+ CFR1 = x3x*x4x*rx3x2*rx4x2
+ CFR2 =-x2x*x4x*rx3x2*rx4x3
+ CFR3 = x2x*x3x*rx4x2*rx4x3
+ CRR =-x2x*rx3x2
+ this%cx0(n)=CFL1*CLL
+ this%cx1(n)=CFL2*CLL+CFR1*CRR
+ this%cx2(n)=CFL3*CLL+CFR2*CRR
+ this%cx3(n)=CFR3*CRR
+ enddo
+
+ do m=1,this%mm
+ j=this%jref(m)
+ y1=yf(j)
+ y2=yf(j+1)
+ y3=yf(j+2)
+ y4=yf(j+3)
+ y = ya(m)
+ y1y = y1-y
+ y2y = y2-y
+ y3y = y3-y
+ y4y = y4-y
+ ry2y1 = 1./(y2-y1)
+ ry3y1 = 1./(y3-y1)
+ ry4y1 = 1./(y4-y1)
+ ry3y2 = 1./(y3-y2)
+ ry4y2 = 1./(y4-y2)
+ ry4y3 = 1./(y4-y3)
+ CFL1 = y2y*y3y*ry2y1*ry3y1
+ CFL2 =-y1y*y3y*ry2y1*ry3y2
+ CFL3 = y1y*y2y*ry3y1*ry3y2
+ CLL = y3y*ry3y2
+ CFR1 = y3y*y4y*ry3y2*ry4y2
+ CFR2 =-y2y*y4y*ry3y2*ry4y3
+ CFR3 = y2y*y3y*ry4y2*ry4y3
+ CRR =-y2y*ry3y2
+ this%cy0(m)=CFL1*CLL
+ this%cy1(m)=CFL2*CLL+CFR1*CRR
+ this%cy2(m)=CFL3*CLL+CFR2*CRR
+ this%cy3(m)=CFR3*CRR
+ enddo
+
+!
+! Quadratic interpolations
+!
+ do n=1,this%nm
+ i=this%irefq(n)
+ x1=xf(i)
+ x2=xf(i+1)
+ x3=xf(i+2)
+ x = xa(n)
+ x1_x = x1-x
+ x2_x = x2-x
+ x3_x = x3-x
+ rx2x1 = 1./(x2-x1)
+ rx3x1 = 1./(x3-x1)
+ rx3x2 = 1./(x3-x2)
+ this%qx0(n) = x2_x*x3_x*rx2x1*rx3x1
+ this%qx1(n) =-x1_x*x3_x*rx2x1*rx3x2
+ this%qx2(n) = x1_x*x2_x*rx3x1*rx3x2
+ enddo
+
+ do m=1,this%mm
+ i=this%jrefq(m)
+ y1=yf(i)
+ y2=yf(i+1)
+ y3=yf(i+2)
+ y = ya(m)
+ y1_y = y1-y
+ y2_y = y2-y
+ y3_y = y3-y
+ ry2y1 = 1./(y2-y1)
+ ry3y1 = 1./(y3-y1)
+ ry3y2 = 1./(y3-y2)
+ this%qy0(m) = y2_y*y3_y*ry2y1*ry3y1
+ this%qy1(m) =-y1_y*y3_y*ry2y1*ry3y2
+ this%qy2(m) = y1_y*y2_y*ry3y1*ry3y2
+ enddo
+
+!
+! Linear interpolations
+!
+ do n=1,this%nm
+ i=this%irefL(n)
+ x1=xf(i)
+ x2=xf(i+1)
+ x = xa(n)
+ x1_x = x1-x
+ x2_x = x2-x
+ rx2x1 = 1./(x2-x1)
+ this%Lx0(n) = x2_x*rx2x1
+ this%Lx1(n) =-x1_x*rx2x1
+ enddo
+
+ do m=1,this%mm
+ j=this%jrefL(m)
+ y1=yf(j)
+ y2=yf(j+1)
+ y = ya(m)
+ y1_y = y1-y
+ y2_y = y2-y
+ ry2y1 = 1./(y2-y1)
+ this%Ly0(m) = y2_y*ry2y1
+ this%Ly1(m) =-y1_y*ry2y1
+ enddo
+!-----------------------------------------------------------------------
+endsubroutine lsqr_mg_coef
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine lwq_vertical_coef &
+!***********************************************************************
+! !
+! Prepare coeficients for vertical mapping between: !
+! analysis grid vertical resolution (nm) and !
+! generation one of filter grid vertical resoluition (im) !
+! !
+! ( im <= nm ) !
+! !
+!***********************************************************************
+(this,nm_in,im_in,c1,c2,c3,c4,iref_out)
+implicit none
+class(mg_intstate_type),target::this
+
+integer(i_kind), intent(in):: nm_in,im_in
+real(r_kind), dimension(1:nm_in), intent(out):: c1,c2,c3,c4
+integer(i_kind), dimension(1:nm_in), intent(out):: iref_out
+
+real(r_kind), dimension(1:nm_in):: y
+real(r_kind), dimension(0:im_in+1):: x
+real(r_kind):: dy,x1,x2,x3,x4,dx1,dx2,dx3,dx4
+real(r_kind):: dx13,dx23,dx24
+
+integer(i_kind):: i,n
+!-----------------------------------------------------------------------
+
+ do i=0,im_in+1
+ x(i)=(i-1)*1.
+ enddo
+
+ dy = 1.*(im_in-1)/(nm_in-1)
+ do n=1,nm_in
+ y(n)=(n-1)*dy
+ enddo
+ y(nm_in)=x(im_in)
+
+ do n=2,nm_in-1
+ i = y(n)+1
+ x1 = x(i-1)
+ x2 = x(i)
+ x3 = x(i+1)
+ x4 = x(i+2)
+ iref_out(n)=i
+ dx1 = y(n)-x1
+ dx2 = y(n)-x2
+ dx3 = y(n)-x3
+ dx4 = y(n)-x4
+ dx13 = dx1*dx3
+ dx23 = 0.5*dx2*dx3
+ dx24 = dx2*dx4
+ c1(n) = -dx23*dx3
+ c2(n) = ( dx13+0.5*dx24)*dx3
+ c3(n) = -(0.5*dx13+ dx24)*dx2
+ c4(n) = dx23*dx2
+
+ if(iref_out(n)==1) then
+ c3(n)=c3(n)+c1(n)
+ c1(n)=0.
+ endif
+ if(iref_out(n)==im_in-1) then
+ c2(n)=c2(n)+c4(n)
+ c4(n)=0.
+ endif
+ enddo
+ iref_out(1)=1; c1(1)=0.; c2(1)=1.; c3(1)=0.; c4(1)=0.
+ iref_out(nm_in)=im_in; c1(nm_in)=0.; c2(nm_in)=1.; c3(nm_in)=0.; c4(n)=0.
+
+!-----------------------------------------------------------------------
+endsubroutine lwq_vertical_coef
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine lwq_vertical_adjoint &
+!***********************************************************************
+! !
+! Direct linerly weighted quadratic adjoint interpolation in vertical !
+! from reslution nm to resolution km !
+! !
+! ( km <= nm ) !
+! !
+!***********************************************************************
+(this,nm_in,km_in,imin,imax,jmin,jmax,c1,c2,c3,c4,kref,w,f)
+implicit none
+!-----------------------------------------------------------------------
+class(mg_intstate_type),target::this
+integer(i_kind), intent(in):: nm_in,km_in,imin,imax,jmin,jmax
+real(r_kind), dimension(1:nm_in), intent(in):: c1,c2,c3,c4
+integer(i_kind), dimension(1:nm_in), intent(in):: kref
+real(r_kind), dimension(1:nm_in,imin:imax,jmin:jmax), intent(in):: w
+real(r_kind), dimension(1:km_in,imin:imax,jmin:jmax), intent(out):: f
+integer(i_kind):: k,n
+!-----------------------------------------------------------------------
+ f = 0.
+do n=2,nm_in-1
+ k = kref(n)
+ if( k==1 ) then
+ f(1,:,:) = f(1,:,:)+c2(n)*w(n,:,:)
+ f(2,:,:) = f(2,:,:)+c3(n)*w(n,:,:)
+ f(3,:,:) = f(3,:,:)+c4(n)*w(n,:,:)
+ elseif &
+ ( k==km_in-1) then
+ f(km_in-2,:,:) = f(km_in-2,:,:)+c1(n)*w(n,:,:)
+ f(km_in-1,:,:) = f(km_in-1,:,:)+c2(n)*w(n,:,:)
+ f(km_in ,:,:) = f(km_in ,:,:)+c3(n)*w(n,:,:)
+ elseif( k==km_in) then
+ f(k ,:,:) = f(k ,:,:)+c2(n)*w(n,:,:)
+ else
+ f(k-1,:,:) = f(k-1,:,:)+c1(n)*w(n,:,:)
+ f(k ,:,:) = f(k ,:,:)+c2(n)*w(n,:,:)
+ f(k+1,:,:) = f(k+1,:,:)+c3(n)*w(n,:,:)
+ f(k+2,:,:) = f(k+2,:,:)+c4(n)*w(n,:,:)
+ endif
+enddo
+ f(1,:,:)=f(1,:,:)+w(1,:,:)
+ f(km_in,:,:)=f(km_in,:,:)+w(nm_in,:,:)
+
+!-----------------------------------------------------------------------
+endsubroutine lwq_vertical_adjoint
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine lwq_vertical_direct &
+!***********************************************************************
+! !
+! Linerly weighted direct quadratic interpolation in vertical !
+! from reslouion km to resolution nm !
+! !
+! ( km <= nm ) !
+! !
+!***********************************************************************
+(this,km_in,nm_in,imin,imax,jmin,jmax,c1,c2,c3,c4,kref,f,w)
+implicit none
+!-----------------------------------------------------------------------
+class(mg_intstate_type),target::this
+integer(i_kind), intent(in):: km_in,nm_in,imin,imax,jmin,jmax
+real(r_kind), dimension(1:nm_in), intent(in):: c1,c2,c3,c4
+integer(i_kind), dimension(1:nm_in), intent(in):: kref
+real(r_kind), dimension(1:km_in,imin:imax,jmin:jmax), intent(in):: f
+real(r_kind), dimension(1:nm_in,imin:imax,jmin:jmax), intent(out):: w
+integer(i_kind):: k,n
+!-----------------------------------------------------------------------
+do n=2,nm_in-1
+ k = kref(n)
+ if( k==1 ) then
+ w(n,:,:) = c2(n)*f(k,:,:)+c3(n)*f(k+1,:,:)+c4(n)*f(k+2,:,:)
+ elseif &
+ ( k==km_in-1) then
+ w(n,:,:) =c1(n)*f(k-1,:,:)+c2(n)*f(k,:,:)+c3(n)*f(k+1,:,:)
+ elseif &
+ ( k==km_in) then
+ w(n,:,:) = c2(n)*f(k,:,:)
+ else
+ w(n,:,:) =c1(n)*f(k-1,:,:)+c2(n)*f(k,:,: )+c3(n)*f(k+1,:,:)+c4(n)*f(k+2,:,:)
+ endif
+enddo
+ w(1,:,:)=f(1,:,:)
+ w(nm_in,:,:)=f(km_in,:,:)
+
+!-----------------------------------------------------------------------
+endsubroutine lwq_vertical_direct
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine lwq_vertical_adjoint_spec &
+!***********************************************************************
+! !
+! Direct linerly weighted quadratic adjoint interpolation in vertical !
+! from reslution nm to resolution km !
+! !
+! ( km <= nm ) !
+! !
+!***********************************************************************
+(this,km3_in,nm_in,km_in,imin,imax,jmin,jmax,c1,c2,c3,c4,kref,W,F)
+implicit none
+!-----------------------------------------------------------------------
+class(mg_intstate_type),target::this
+integer(i_kind), intent(in):: km3_in,nm_in,km_in,imin,imax,jmin,jmax
+real(r_kind), dimension(1:nm_in), intent(in):: c1,c2,c3,c4
+integer(i_kind), dimension(1:nm_in), intent(in):: kref
+real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:nm_in), intent(in):: W
+real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:km_in), intent(out):: F
+integer(i_kind):: k,n
+!-----------------------------------------------------------------------
+ F = 0.
+do n=2,nm_in-1
+ k = kref(n)
+ if( k==1 ) then
+ F(:,:,:,1) = F(:,:,:,1)+c2(n)*W(:,:,:,n)
+ F(:,:,:,2) = F(:,:,:,2)+c3(n)*W(:,:,:,n)
+ F(:,:,:,3) = F(:,:,:,3)+c4(n)*W(:,:,:,n)
+ elseif &
+ ( k==km_in-1) then
+ F(:,:,:,km_in-2) = F(:,:,:,km_in-2)+c1(n)*W(:,:,:,n)
+ F(:,:,:,km_in-1) = F(:,:,:,km_in-1)+c2(n)*W(:,:,:,n)
+ F(:,:,:,km_in ) = F(:,:,:,km_in )+c3(n)*W(:,:,:,n)
+ elseif( k==km_in) then
+ F(:,:,:,k ) = F(:,:,:,k )+c2(n)*W(:,:,:,n)
+ else
+ F(:,:,:,k-1) = F(:,:,:,k-1)+c1(n)*W(:,:,:,n)
+ F(:,:,:,k ) = F(:,:,:,k )+c2(n)*W(:,:,:,n)
+ F(:,:,:,k+1) = F(:,:,:,k+1)+c3(n)*W(:,:,:,n)
+ F(:,:,:,k+2) = F(:,:,:,k+2)+c4(n)*W(:,:,:,n)
+ endif
+enddo
+ F(:,:,:,1 )=F(:,:,:,1 )+W(:,:,:,1 )
+ F(:,:,:,km_in)=F(:,:,:,km_in)+W(:,:,:,nm_in)
+!-----------------------------------------------------------------------
+endsubroutine lwq_vertical_adjoint_spec
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine lwq_vertical_direct_spec &
+!***********************************************************************
+! !
+! Linerly weighted direct quadratic interpolation in vertical !
+! from reslouion im to resolution nm !
+! !
+! ( km <= nm ) !
+! !
+!***********************************************************************
+(this,km3_in,km_in,nm_in,imin,imax,jmin,jmax,c1,c2,c3,c4,kref,F,W)
+implicit none
+!-----------------------------------------------------------------------
+class(mg_intstate_type),target::this
+integer(i_kind), intent(in):: km3_in,km_in,nm_in,imin,imax,jmin,jmax
+real(r_kind), dimension(1:nm_in), intent(in):: c1,c2,c3,c4
+integer(i_kind), dimension(1:nm_in), intent(in):: kref
+real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:km_in), intent(in):: F
+real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:nm_in), intent(out):: W
+integer(i_kind):: k,n
+!-----------------------------------------------------------------------
+do n=2,nm_in-1
+ k = kref(n)
+ if( k==1 ) then
+ W(:,:,:,n) = c2(n)*F(:,:,:,k)+c3(n)*F(:,:,:,k+1)+c4(n)*F(:,:,:,k+2)
+ elseif &
+ ( k==km_in-1) then
+ W(:,:,:,n) =c1(n)*F(:,:,:,k-1)+c2(n)*F(:,:,:,k)+c3(n)*F(:,:,:,k+1)
+ elseif &
+ ( k==km_in) then
+ W(:,:,:,n) = c2(n)*F(:,:,:,k)
+ else
+ W(:,:,:,n) =c1(n)*F(:,:,:,k-1)+c2(n)*F(:,:,:,k)+c3(n)*F(:,:,:,k+1)+c4(n)*F(:,:,:,k+2)
+ endif
+enddo
+ W(:,:,:,1 )=F(:,:,:,1 )
+ W(:,:,:,nm_in)=F(:,:,:,km_in)
+!-----------------------------------------------------------------------
+endsubroutine lwq_vertical_direct_spec
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine l_vertical_adjoint_spec &
+!***********************************************************************
+! !
+! Adjoint of linear interpolations in vertical !
+! from reslution nm to resolution km !
+! !
+! ( nm = 2*km-1 ) !
+! !
+!***********************************************************************
+(this,km3_in,nm_in,km_in,imin,imax,jmin,jmax,W,F)
+implicit none
+!-----------------------------------------------------------------------
+class(mg_intstate_type),target::this
+integer(i_kind), intent(in):: km3_in,nm_in,km_in,imin,imax,jmin,jmax
+real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:nm_in), intent(in):: W
+real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:km_in), intent(out):: F
+integer(i_kind):: k,n
+!-----------------------------------------------------------------------
+ F = 0.
+
+ k=1
+ do n=2,nm_in-1,2
+ F(:,:,:,k ) = F(:,:,:,k )+0.5*W(:,:,:,n)
+ F(:,:,:,k+1) = F(:,:,:,k+1)+0.5*W(:,:,:,n)
+ k=k+1
+ enddo
+
+ k=1
+ do n=1,nm_in,2
+ F(:,:,:,k ) = F(:,:,:,k )+ W(:,:,:,n)
+ k=k+1
+ enddo
+!-----------------------------------------------------------------------
+endsubroutine l_vertical_adjoint_spec
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine l_vertical_direct_spec &
+!***********************************************************************
+! !
+! !
+! Direct linear interpolations in vertical !
+! from reslution nm to resolution km !
+! !
+! ( nm = 2*km-1 ) !
+! !
+!***********************************************************************
+(this,km3_in,km_in,nm_in,imin,imax,jmin,jmax,F,W)
+implicit none
+!-----------------------------------------------------------------------
+class(mg_intstate_type),target::this
+integer(i_kind), intent(in):: km3_in,km_in,nm_in,imin,imax,jmin,jmax
+real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:km_in), intent(in):: F
+real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:nm_in), intent(out):: W
+integer(i_kind):: k,n
+!-----------------------------------------------------------------------
+ k=1
+ do n=1,nm_in,2
+ W(:,:,:,n) =F (:,:,:,k)
+ k=k+1
+ enddo
+
+ k=1
+ do n=2,nm_in-1,2
+ W(:,:,:,n) = 0.5*(F(:,:,:,k)+F(:,:,:,k+1))
+ k=k+1
+ enddo
+!-----------------------------------------------------------------------
+endsubroutine l_vertical_direct_spec
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine lsqr_direct_offset &
+!***********************************************************************
+! !
+! Given a source array V(km,1-ib:im+ib,1-jb:jm+jb) perform !
+! direct interpolations to get target array W(km,1:nm,1:mm) !
+! using two passes of 1d interpolator !
+! !
+!***********************************************************************
+(this,V_in,W,km_in,ibm,jbm)
+!-----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: km_in,ibm,jbm
+real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(in):: V_in
+real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(out):: W
+
+real(r_kind), dimension(km_in,1:this%nm,1-jbm:this%jm+jbm):: VX
+integer(i_kind):: i,j,n,m
+real(r_kind),dimension(km_in):: v0,v1,v2,v3
+!-----------------------------------------------------------------------
+ do j=1-jbm,this%jm+jbm
+ do n=1,this%nm
+ i = this%iref(n)
+ v0(:)=V_in(:,i ,j)
+ v1(:)=V_in(:,i+1,j)
+ v2(:)=V_in(:,i+2,j)
+ v3(:)=V_in(:,i+3,j)
+ VX(:,n,j) = this%cx0(n)*v0(:)+this%cx1(n)*v1(:)+this%cx2(n)*v2(:)+this%cx3(n)*v3(:)
+ enddo
+ enddo
+
+ do m=1,this%mm
+ j = this%jref(m)
+ do n=1,this%nm
+ v0(:)=VX(:,n,j )
+ v1(:)=VX(:,n,j+1)
+ v2(:)=VX(:,n,j+2)
+ v3(:)=VX(:,n,j+3)
+ W(:,n,m) = this%cy0(m)*v0(:)+this%cy1(m)*v1(:)+this%cy2(m)*v2(:)+this%cy3(m)*v3(:)
+ enddo
+ enddo
+!-----------------------------------------------------------------------
+endsubroutine lsqr_direct_offset
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine lsqr_adjoint_offset &
+!***********************************************************************
+! !
+! Given a target array W(km,1:nm,1:mm) perform adjoint !
+! interpolations to get source array V(km,1-ib:im+ib,1-jb:jm+jb) !
+! using two passes of 1d interpolator !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,V_out,km_in,ibm,jbm)
+!-----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind):: km_in,ibm,jbm
+real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(in):: W
+real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(out):: V_out
+real(r_kind), dimension(km_in,1:this%nm,1-jbm:this%jm+jbm):: VX
+real(r_kind), dimension(km_in):: wk
+real(r_kind), dimension(km_in):: vxk
+integer(i_kind):: i,j,n,m,l,k
+real(r_kind):: c0,c1,c2,c3
+!-----------------------------------------------------------------------
+ V_out(:,:,:)=0.
+ VX(:,:,:)=0.
+
+ do m=1,this%mm
+ j = this%jref(m)
+ c0 = this%cy0(m)
+ c1 = this%cy1(m)
+ c2 = this%cy2(m)
+ c3 = this%cy3(m)
+ do n=1,this%nm
+ wk(:)=W(:,n,m)
+ VX(:,n,j ) = VX(:,n,j )+wk(:)*c0
+ VX(:,n,j+1) = VX(:,n,j+1)+wk(:)*c1
+ VX(:,n,j+2) = VX(:,n,j+2)+wk(:)*c2
+ VX(:,n,j+3) = VX(:,n,j+3)+wk(:)*c3
+ enddo
+ enddo
+
+ do n=1,this%nm
+ i = this%iref(n)
+ c0 = this%cx0(n)
+ c1 = this%cx1(n)
+ c2 = this%cx2(n)
+ c3 = this%cx3(n)
+ do j=1-jbm,this%jm+jbm
+ vxk(:)=VX(:,n,j)
+ V_out(:,i ,j) = V_out(:,i ,j)+vxk(:)*c0
+ V_out(:,i+1,j) = V_out(:,i+1,j)+vxk(:)*c1
+ V_out(:,i+2,j) = V_out(:,i+2,j)+vxk(:)*c2
+ V_out(:,i+3,j) = V_out(:,i+3,j)+vxk(:)*c3
+ enddo
+ enddo
+!-----------------------------------------------------------------------
+endsubroutine lsqr_adjoint_offset
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine quad_direct_offset &
+!***********************************************************************
+! !
+! Given a source array V(km,1-ib:im+ib,1-jb:jm+jb) perform !
+! direct interpolations to get target array W(km,1:nm,1:mm) !
+! using two passes of 1d interpolator !
+! !
+!***********************************************************************
+(this,V_in,W,km_in,ibm,jbm)
+!-----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: km_in,ibm,jbm
+real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(in):: V_in
+real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(out):: W
+real(r_kind), dimension(km_in,1:this%nm,1-jbm:this%jm+jbm):: VX
+integer(i_kind):: i,j,n,m
+real(r_kind),dimension(km_in):: v0,v1,v2
+!-----------------------------------------------------------------------
+ do n=1,this%nm
+ i = this%irefq(n)
+ do j=1-jbm,this%jm+jbm
+ v0(:)=V_in(:,i ,j)
+ v1(:)=V_in(:,i+1,j)
+ v2(:)=V_in(:,i+2,j)
+ VX(:,n,j) = this%qx0(n)*v0(:)+this%qx1(n)*v1(:)+this%qx2(n)*v2(:)
+ enddo
+ enddo
+
+ do m=1,this%mm
+ j = this%jrefq(m)
+ do n=1,this%nm
+ v0(:)=VX(:,n,j )
+ v1(:)=VX(:,n,j+1)
+ v2(:)=VX(:,n,j+2)
+ W(:,n,m) = this%qy0(m)*v0(:)+this%qy1(m)*v1(:)+this%qy2(m)*v2(:)
+ enddo
+ enddo
+!-----------------------------------------------------------------------
+endsubroutine quad_direct_offset
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine quad_adjoint_offset &
+!***********************************************************************
+! !
+! Given a target array W(km,1:nm,1:mm) perform adjoint !
+! interpolations to get source array V(km,1-ib:im+ib,1-jb:jm+jb) !
+! using two passes of 1d interpolator !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,V_out,km_in,ibm,jbm)
+!-----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind):: km_in,ibm,jbm
+real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(in):: W
+real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(out):: V_out
+real(r_kind), dimension(km_in,1:this%nm,1-jbm:this%jm+jbm):: VX
+real(r_kind), dimension(km_in):: wk
+real(r_kind), dimension(km_in):: vxk
+integer(i_kind):: i,j,n,m,l,k
+real(r_kind):: c0,c1,c2
+!-----------------------------------------------------------------------
+ V_out(:,:,:)=0.
+ VX(:,:,:)=0.
+
+ do m=1,this%mm
+ j = this%jrefq(m)
+ c0 = this%qy0(m)
+ c1 = this%qy1(m)
+ c2 = this%qy2(m)
+ do n=1,this%nm
+ wk(:)=W(:,n,m)
+ VX(:,n,j ) = VX(:,n,j )+wk(:)*c0
+ VX(:,n,j+1) = VX(:,n,j+1)+wk(:)*c1
+ VX(:,n,j+2) = VX(:,n,j+2)+wk(:)*c2
+ enddo
+ enddo
+
+
+ do n=1,this%nm
+ i = this%irefq(n)
+ c0 = this%qx0(n)
+ c1 = this%qx1(n)
+ c2 = this%qx2(n)
+ do j=1-jbm,this%jm+jbm
+ vxk(:)=VX(:,n,j)
+ V_out(:,i ,j) = V_out(:,i ,j)+vxk(:)*c0
+ V_out(:,i+1,j) = V_out(:,i+1,j)+vxk(:)*c1
+ V_out(:,i+2,j) = V_out(:,i+2,j)+vxk(:)*c2
+ enddo
+ enddo
+!-----------------------------------------------------------------------
+endsubroutine quad_adjoint_offset
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine lin_direct_offset &
+!***********************************************************************
+! !
+! Given a source array V(km,1-ib:im+ib,1-jb:jm+jb) perform !
+! direct interpolations to get target array W(km,1:nm,1:mm) !
+! using two passes of 1d linear interpolator !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,V_in,W,km_in,ibm,jbm)
+!-----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind),intent(in):: km_in,ibm,jbm
+real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(in):: V_in
+real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(out):: W
+real(r_kind), dimension(km_in,1:this%nm,1-jbm:this%jm+jbm):: VX
+integer(i_kind):: i,j,n,m
+real(r_kind),dimension(km_in):: v0,v1
+!-----------------------------------------------------------------------
+ do n=1,this%nm
+ i = this%irefL(n)
+ do j=1-jbm,this%jm+jbm
+ v0(:)=V_in(:,i ,j)
+ v1(:)=V_in(:,i+1,j)
+ VX(:,n,j) = this%Lx0(n)*v0(:)+this%Lx1(n)*v1(:)
+ enddo
+ enddo
+
+ do m=1,this%mm
+ j = this%jrefL(m)
+ do n=1,this%nm
+ v0(:)=VX(:,n,j )
+ v1(:)=VX(:,n,j+1)
+ W(:,n,m) = this%Ly0(m)*v0(:)+this%Ly1(m)*v1(:)
+ enddo
+ enddo
+!-----------------------------------------------------------------------
+endsubroutine lin_direct_offset
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine lin_adjoint_offset &
+!***********************************************************************
+! !
+! Given a target array W(km,1:nm,1:mm) perform adjoint !
+! interpolations to get source array V(km,1-ib:im+ib,1-jb:jm+jb) !
+! using two passes of 1d linear interpolator !
+! !
+! - offset version - !
+! !
+!***********************************************************************
+(this,W,V_out,km_in,ibm,jbm)
+!-----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind):: km_in,ibm,jbm
+real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(in):: W
+real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(out):: V_out
+real(r_kind), dimension(km_in,1:this%nm,1-jbm:this%jm+jbm):: VX
+real(r_kind), dimension(km_in):: wk
+real(r_kind), dimension(km_in):: vxk
+integer(i_kind):: i,j,n,m,l,k
+real(r_kind):: c0,c1
+!-----------------------------------------------------------------------
+ V_out(:,:,:)=0.
+ VX(:,:,:)=0.
+
+ do m=1,this%mm
+ j = this%jrefL(m)
+ c0 = this%Ly0(m)
+ c1 = this%Ly1(m)
+ do n=1,this%nm
+ wk(:)=W(:,n,m)
+ VX(:,n,j ) = VX(:,n,j )+wk(:)*c0
+ VX(:,n,j+1) = VX(:,n,j+1)+wk(:)*c1
+ enddo
+ enddo
+
+ do n=1,this%nm
+ i = this%irefL(n)
+ c0 = this%Lx0(n)
+ c1 = this%Lx1(n)
+ do j=1-jbm,this%jm+jbm
+ vxk(:)=VX(:,n,j)
+ V_out(:,i ,j) = V_out(:,i ,j)+vxk(:)*c0
+ V_out(:,i+1,j) = V_out(:,i+1,j)+vxk(:)*c1
+ enddo
+ enddo
+!-----------------------------------------------------------------------
+endsubroutine lin_adjoint_offset
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine l_vertical_adjoint_spec2 &
+!***********************************************************************
+! !
+! Adjoint of linear interpolations in vertical !
+! from reslution nm to resolution km !
+! !
+! ( nm = 2*km-1 ) !
+! !
+!***********************************************************************
+(this,en,nm_in,km_in,imin,imax,jmin,jmax,W,F)
+implicit none
+!-----------------------------------------------------------------------
+class(mg_intstate_type),target::this
+integer(i_kind), intent(in):: en,nm_in,km_in,imin,imax,jmin,jmax
+real(r_kind), dimension(1:nm_in*en,imin:imax,jmin:jmax), intent(in):: W
+real(r_kind), dimension(1:km_in*en,imin:imax,jmin:jmax), intent(out):: F
+integer(i_kind):: k,n,e,enm,ekm
+!-----------------------------------------------------------------------
+ F = 0.
+
+do e=0,en-1
+ enm = e*nm_in
+ ekm = e*km_in
+ k=1
+ do n=2,nm_in-1,2
+ F(ekm+k ,:,:) = F(ekm+k ,:,:)+0.5*W(enm+n,:,:)
+ F(ekm+k+1,:,:) = F(ekm+k+1,:,:)+0.5*W(enm+n,:,:)
+ k=k+1
+ enddo
+
+ k=1
+ do n=1,nm_in,2
+ F(ekm+k,:,:) = F(ekm+k,:,:) + W(enm+n,:,:)
+ k=k+1
+ enddo
+enddo
+!-----------------------------------------------------------------------
+endsubroutine l_vertical_adjoint_spec2
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine l_vertical_direct_spec2 &
+!***********************************************************************
+! !
+! !
+! Direct linear interpolations in vertical !
+! from reslution nm to resolution km !
+! !
+! ( nmax = 2*kmax-1 ) !
+! !
+!***********************************************************************
+(this,en,km_in,nm_in,imin,imax,jmin,jmax,F,W)
+implicit none
+!-----------------------------------------------------------------------
+class(mg_intstate_type),target::this
+integer(i_kind), intent(in):: en,km_in,nm_in,imin,imax,jmin,jmax
+real(r_kind), dimension(1:km_in*en,imin:imax,jmin:jmax), intent(in):: F
+real(r_kind), dimension(1:nm_in*en,imin:imax,jmin:jmax), intent(out):: W
+integer(i_kind):: k,n,e,enm,ekm
+!-----------------------------------------------------------------------
+do e=0,en-1
+ enm = e*nm_in
+ ekm = e*km_in
+ k=1
+ do n=1,nm_in,2
+ W(enm+n,:,:) =F (ekm+k,:,:)
+ k=k+1
+ enddo
+ k=1
+ do n=2,nm_in-1,2
+ W(enm+n,:,:) = 0.5*(F(ekm+k,:,:)+F(ekm+k+1,:,:))
+ k=k+1
+ enddo
+enddo
+!-----------------------------------------------------------------------
+endsubroutine l_vertical_direct_spec2
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+end submodule mg_interpolate
diff --git a/src/mgbf/mg_intstate.f90 b/src/mgbf/mg_intstate.f90
new file mode 100644
index 0000000000..932084c705
--- /dev/null
+++ b/src/mgbf/mg_intstate.f90
@@ -0,0 +1,1394 @@
+module mg_intstate
+!$$$ submodule documentation block
+! . . . .
+! module: mg_intstate
+! prgmmr: rancic org: NCEP/EMC date: 2020
+!
+! abstract: Contains declarations and allocations of internal
+! state variables use for filtering (offset version)
+!
+! module history log:
+! 2023-04-19 lei - object-oriented coding
+! 2024-01-11 rancic - optimization for ensemble localization
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! allocate_mg_intstate -
+! def_mg_weights -
+! init_mg_line -
+! deallocate_mg_intstate -
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+use kinds, only: r_kind,i_kind
+use jp_pkind2, only: fpi
+use jp_pbfil3, only: inimomtab,t22_to_3,tritform,t33_to_6,hextform
+use mg_parameter,only: mg_parameter_type
+implicit none
+type,extends( mg_parameter_type):: mg_intstate_type
+real(r_kind), allocatable,dimension(:,:,:):: V
+!
+! Composite control variable on first generation of filter grid
+!
+real(r_kind), allocatable,dimension(:,:,:):: VALL
+!
+! Composite control variable on high generations of filter grid
+!
+real(r_kind), allocatable,dimension(:,:,:):: HALL
+
+real(r_kind), allocatable,dimension(:,:,:):: a_diff_f
+real(r_kind), allocatable,dimension(:,:,:):: a_diff_h
+real(r_kind), allocatable,dimension(:,:,:):: b_diff_f
+real(r_kind), allocatable,dimension(:,:,:):: b_diff_h
+
+!
+! Localization weights
+!
+real(r_kind), allocatable,dimension(:,:,:):: w1_loc
+real(r_kind), allocatable,dimension(:,:,:):: w2_loc
+real(r_kind), allocatable,dimension(:,:,:):: w3_loc
+real(r_kind), allocatable,dimension(:,:,:):: w4_loc
+
+real(r_kind), allocatable,dimension(:,:):: p_eps
+real(r_kind), allocatable,dimension(:,:):: p_del
+real(r_kind), allocatable,dimension(:,:):: p_sig
+real(r_kind), allocatable,dimension(:,:):: p_rho
+
+real(r_kind), allocatable,dimension(:,:,:):: paspx
+real(r_kind), allocatable,dimension(:,:,:):: paspy
+real(r_kind), allocatable,dimension(:,:,:):: pasp1
+real(r_kind), allocatable,dimension(:,:,:,:):: pasp2
+real(r_kind), allocatable,dimension(:,:,:,:,:):: pasp3
+
+real(r_kind), allocatable,dimension(:,:,:):: vpasp2
+real(r_kind), allocatable,dimension(:,:,:):: hss2
+real(r_kind), allocatable,dimension(:,:,:,:):: vpasp3
+real(r_kind), allocatable,dimension(:,:,:,:):: hss3
+
+real(r_kind), allocatable,dimension(:):: ssx
+real(r_kind), allocatable,dimension(:):: ssy
+real(r_kind), allocatable,dimension(:):: ss1
+real(r_kind), allocatable,dimension(:,:):: ss2
+real(r_kind), allocatable,dimension(:,:,:):: ss3
+
+integer(fpi), allocatable,dimension(:,:,:):: dixs
+integer(fpi), allocatable,dimension(:,:,:):: diys
+integer(fpi), allocatable,dimension(:,:,:):: dizs
+
+integer(fpi), allocatable,dimension(:,:,:,:):: dixs3
+integer(fpi), allocatable,dimension(:,:,:,:):: diys3
+integer(fpi), allocatable,dimension(:,:,:,:):: dizs3
+
+integer(fpi), allocatable,dimension(:,:,:,:):: qcols
+
+integer(i_kind),allocatable,dimension(:):: iref,jref
+integer(i_kind),allocatable,dimension(:):: irefq,jrefq
+integer(i_kind),allocatable,dimension(:):: irefL,jrefL
+
+integer(i_kind),allocatable,dimension(:):: Lref,Lref_h
+real(r_kind),allocatable,dimension(:):: cvf1,cvf2,cvf3,cvf4
+real(r_kind),allocatable,dimension(:):: cvh1,cvh2,cvh3,cvh4
+
+real(r_kind),allocatable,dimension(:):: cx0,cx1,cx2,cx3
+real(r_kind),allocatable,dimension(:):: cy0,cy1,cy2,cy3
+
+real(r_kind),allocatable,dimension(:):: qx0,qx1,qx2
+real(r_kind),allocatable,dimension(:):: qy0,qy1,qy2
+
+real(r_kind),allocatable,dimension(:):: Lx0,Lx1
+real(r_kind),allocatable,dimension(:):: Ly0,Ly1
+
+real(r_kind),allocatable,dimension(:):: p_coef,q_coef
+real(r_kind),allocatable,dimension(:):: a_coef,b_coef
+
+real(r_kind),allocatable,dimension(:,:):: cf00,cf01,cf02,cf03 &
+ ,cf10,cf11,cf12,cf13 &
+ ,cf20,cf21,cf22,cf23 &
+ ,cf30,cf31,cf32,cf33
+contains
+ procedure :: allocate_mg_intstate,deallocate_mg_intstate
+ procedure :: def_mg_weights,init_mg_line
+!from mg_interpolate.f90
+ procedure :: def_offset_coef
+ procedure :: lsqr_mg_coef,lwq_vertical_coef
+ procedure :: lwq_vertical_direct,lwq_vertical_adjoint
+ procedure :: lwq_vertical_direct_spec,lwq_vertical_adjoint_spec
+ procedure :: l_vertical_direct_spec,l_vertical_adjoint_spec
+ procedure :: l_vertical_direct_spec2,l_vertical_adjoint_spec2
+ procedure :: lsqr_direct_offset,lsqr_adjoint_offset
+ procedure :: quad_direct_offset,quad_adjoint_offset
+ procedure :: lin_direct_offset,lin_adjoint_offset
+!from mg_bocos.f90
+ generic :: boco_2d => boco_2d_g1,boco_2d_gh
+ procedure :: boco_2d_g1,boco_2d_gh
+ generic :: boco_3d => boco_3d_g1,boco_3d_gh
+ procedure :: boco_3d_g1,boco_3d_gh
+ generic :: bocoT_2d => bocoT_2d_g1,bocoT_2d_gh
+ procedure :: bocoT_2d_g1,bocoT_2d_gh
+ generic :: bocoTx => bocoTx_2d_g1,bocoTx_2d_gh
+ procedure :: bocoTx_2d_g1,bocoTx_2d_gh
+ generic :: bocoTy => bocoTy_2d_g1,bocoTy_2d_gh
+ procedure :: bocoTy_2d_g1,bocoTy_2d_gh
+ generic :: bocoT_3d => bocoT_3d_g1,bocoT_3d_gh
+ procedure :: bocoT_3d_g1,bocoT_3d_gh
+ generic :: bocox => bocox_2d_g1,bocox_2d_gh
+ procedure :: bocox_2d_g1,bocox_2d_gh
+ generic :: bocoy => bocoy_2d_g1,bocoy_2d_gh
+ procedure :: bocoy_2d_g1,bocoy_2d_gh
+ generic :: upsend_all => upsend_all_g1,upsend_all_gh
+ procedure :: upsend_all_g1,upsend_all_gh
+ generic :: downsend_all => downsend_all_g2,downsend_all_gh
+ procedure :: downsend_all_g2,downsend_all_gh
+ procedure :: boco_2d_loc
+ procedure :: bocoT_2d_loc
+ procedure :: upsend_loc_g12
+ procedure :: upsend_loc_g23
+ procedure :: upsend_loc_g34
+ procedure :: downsend_loc_g43
+ procedure :: downsend_loc_g32
+ procedure :: downsend_loc_g21
+!from mg_generation.f90
+ procedure:: upsending_all,downsending_all,weighting_all
+ procedure:: upsending,downsending
+ procedure:: upsending_highest,downsending_highest
+ procedure:: upsending2,downsending2
+ procedure:: upsending_ens,downsending_ens
+ procedure:: upsending2_ens,downsending2_ens
+ procedure:: upsending_ens_nearest,downsending_ens_nearest
+ generic :: upsending_loc => upsending_loc_g3,upsending_loc_g4
+ procedure:: upsending_loc_g3,upsending_loc_g4
+ generic :: downsending_loc => downsending_loc_g3,downsending_loc_g4
+ procedure:: downsending_loc_g3,downsending_loc_g4
+ procedure:: weighting_helm,weighting,weighting_highest,weighting_ens
+ generic :: weighting_loc => weighting_loc_g3,weighting_loc_g4
+ procedure:: weighting_loc_g3,weighting_loc_g4
+ procedure:: adjoint,direct1
+ procedure:: adjoint2,direct2
+ procedure:: adjoint_nearest,direct_nearest
+ procedure:: adjoint_highest,direct_highest
+!from mg_filtering.f90
+ procedure :: filtering_procedure
+ procedure :: filtering_rad3,filtering_lin3
+ procedure :: filtering_rad2_bkg,filtering_lin2_bkg,filtering_fast_bkg
+ procedure :: filtering_rad2_ens,filtering_lin2_ens,filtering_fast_ens
+ procedure :: filtering_rad_highest
+ procedure :: sup_vrbeta1T,sup_vrbeta1,sup_vrbeta3T,sup_vrbeta3
+ procedure :: sup_vrbeta1_ens,sup_vrbeta1T_ens
+ procedure :: sup_vrbeta1_bkg,sup_vrbeta1T_bkg
+!from mg_transfer.f90
+ procedure :: anal_to_filt_allmap,filt_to_anal_allmap
+ procedure :: anal_to_filt_all,filt_to_anal_all
+ procedure :: anal_to_filt_all2,filt_to_anal_all2
+ procedure :: composite_to_stack,stack_to_composite
+ procedure :: C2S_ens,S2C_ens
+ procedure :: anal_to_filt,filt_to_anal
+!from mg_entrymod.f90
+ procedure :: mg_initialize
+ procedure :: mg_finalize
+end type mg_intstate_type
+interface
+!from mg_interpolate.f90
+ module subroutine def_offset_coef(this)
+ class(mg_intstate_type),target::this
+ end subroutine
+ module subroutine lsqr_mg_coef(this)
+ class(mg_intstate_type),target::this
+ end subroutine
+ module subroutine lwq_vertical_coef &
+ (this,nm_in,im_in,c1,c2,c3,c4,iref_out)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: nm_in,im_in
+ real(r_kind), dimension(1:nm_in), intent(out):: c1,c2,c3,c4
+ integer(i_kind), dimension(1:nm_in), intent(out):: iref_out
+ end subroutine
+ module subroutine lwq_vertical_direct &
+ (this,km_in,nm_in,imin,imax,jmin,jmax,c1,c2,c3,c4,kref,f,w)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,nm_in,imin,imax,jmin,jmax
+ real(r_kind), dimension(1:nm_in), intent(in):: c1,c2,c3,c4
+ integer(i_kind), dimension(1:nm_in), intent(in):: kref
+ real(r_kind), dimension(1:km_in,imin:imax,jmin:jmax), intent(in):: f
+ real(r_kind), dimension(1:nm_in,imin:imax,jmin:jmax), intent(out):: w
+ end subroutine
+ module subroutine lwq_vertical_adjoint &
+ (this,nm_in,km_in,imin,imax,jmin,jmax,c1,c2,c3,c4,kref,w,f)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: nm_in,km_in,imin,imax,jmin,jmax
+ real(r_kind), dimension(1:nm_in), intent(in):: c1,c2,c3,c4
+ integer(i_kind), dimension(1:nm_in), intent(in):: kref
+ real(r_kind), dimension(1:nm_in,imin:imax,jmin:jmax), intent(in):: w
+ real(r_kind), dimension(1:km_in,imin:imax,jmin:jmax), intent(out):: f
+ end subroutine
+ module subroutine lwq_vertical_direct_spec &
+ (this,km3_in,km_in,nm_in,imin,imax,jmin,jmax,c1,c2,c3,c4,kref,F,W)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km3_in,km_in,nm_in,imin,imax,jmin,jmax
+ real(r_kind), dimension(1:nm_in), intent(in):: c1,c2,c3,c4
+ integer(i_kind), dimension(1:nm_in), intent(in):: kref
+ real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:km_in), intent(in):: F
+ real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:nm_in), intent(out):: W
+ end subroutine
+ module subroutine lwq_vertical_adjoint_spec &
+ (this,km3_in,nm_in,km_in,imin,imax,jmin,jmax,c1,c2,c3,c4,kref,W,F)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km3_in,nm_in,km_in,imin,imax,jmin,jmax
+ real(r_kind), dimension(1:nm_in), intent(in):: c1,c2,c3,c4
+ integer(i_kind), dimension(1:nm_in), intent(in):: kref
+ real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:nm_in), intent(in):: W
+ real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:km_in), intent(out):: F
+ end subroutine
+ module subroutine l_vertical_direct_spec &
+ (this,km3_in,km_in,nm_in,imin,imax,jmin,jmax,F,W)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km3_in,km_in,nm_in,imin,imax,jmin,jmax
+ real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:km_in), intent(in):: F
+ real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:nm_in), intent(out):: W
+ end subroutine
+ module subroutine l_vertical_adjoint_spec &
+ (this,km3_in,nm_in,km_in,imin,imax,jmin,jmax,W,F)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km3_in,nm_in,km_in,imin,imax,jmin,jmax
+ real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:nm_in), intent(in):: W
+ real(r_kind), dimension(1:km3_in,imin:imax,jmin:jmax,1:km_in), intent(out):: F
+ end subroutine
+ module subroutine l_vertical_direct_spec2 &
+ (this,en,km_in,nm_in,imin,imax,jmin,jmax,f,w)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: en,km_in,nm_in,imin,imax,jmin,jmax
+ real(r_kind), dimension(1:km_in*en,imin:imax,jmin:jmax), intent(in):: F
+ real(r_kind), dimension(1:nm_in*en,imin:imax,jmin:jmax), intent(out):: W
+ end subroutine
+ module subroutine l_vertical_adjoint_spec2 &
+ (this,en,nm_in,km_in,imin,imax,jmin,jmax,w,f)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: en,nm_in,km_in,imin,imax,jmin,jmax
+ real(r_kind), dimension(1:nm_in*en,imin:imax,jmin:jmax), intent(in):: W
+ real(r_kind), dimension(1:km_in*en,imin:imax,jmin:jmax), intent(out):: F
+ end subroutine
+ module subroutine lsqr_direct_offset &
+ (this,V_in,W,km_in,ibm,jbm)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: km_in,ibm,jbm
+ real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(in):: V_in
+ real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(out):: W
+ real(r_kind), dimension(km_in,1:this%nm,1-jbm:this%jm+jbm):: VX
+ end subroutine
+ module subroutine lsqr_adjoint_offset &
+ (this,W,V_out,km_in,ibm,jbm)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind):: km_in,ibm,jbm
+ real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(in):: W
+ real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(out):: V_out
+ real(r_kind), dimension(km_in,1:this%nm,1-jbm:this%jm+jbm):: VX
+ end subroutine
+ module subroutine quad_direct_offset &
+ (this,V_in,W,km_in,ibm,jbm)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: km_in,ibm,jbm
+ real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(in):: V_in
+ real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(out):: W
+ real(r_kind), dimension(km_in,1:this%nm,1-jbm:this%jm+jbm):: VX
+ end subroutine
+ module subroutine quad_adjoint_offset &
+ (this,W,V_out,km_in,ibm,jbm)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind):: km_in,ibm,jbm
+ real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(in):: W
+ real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(out):: V_out
+ real(r_kind), dimension(km_in,1:this%nm,1-jbm:this%jm+jbm):: VX
+ end subroutine
+ module subroutine lin_direct_offset &
+ (this,V_in,W,km_in,ibm,jbm)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: km_in,ibm,jbm
+ real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(in):: V_in
+ real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(out):: W
+ end subroutine
+ module subroutine lin_adjoint_offset &
+ (this,W,V_out,km_in,ibm,jbm)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind):: km_in,ibm,jbm
+ real(r_kind), dimension(km_in,1:this%nm,1:this%mm),intent(in):: W
+ real(r_kind), dimension(km_in,1-ibm:this%im+ibm,1-jbm:this%jm+jbm), intent(out):: V_out
+ end subroutine
+!from mg_bocos.f90
+ module subroutine boco_2d_g1 &
+ (this,W,km_in,im_in,jm_in,nbx,nby)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby
+ real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ end subroutine
+ module subroutine boco_2d_gh &
+ (this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+ real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine boco_3d_g1 &
+ (this,W,km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz,Fimax_in,Fjmax_in)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz
+ real(r_kind),dimension(km3_in,1-nbx:im_in+nbx,1-nby:jm_in+nby,1-nbz:Lm_in+nbz),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine boco_3d_gh &
+ (this,W,km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz,mygen_min,mygen_max
+ real(r_kind),dimension(km3_in,1-nbx:im_in+nbx,1-nby:jm_in+nby,1-nbz:Lm_in+nbz),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine bocoT_2d_g1 &
+ (this,W,km_in,im_in,jm_in,nbx,nby)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby
+ real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ end subroutine
+ module subroutine bocoT_2d_gh &
+ (this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+ real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine bocoTx_2d_g1 &
+ (this,W,km_in,im_in,jm_in,nbx,nby)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby
+ real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ end subroutine
+ module subroutine bocoTx_2d_gh &
+ (this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+ real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine bocoTy_2d_g1 &
+ (this,W,km_in,im_in,jm_in,nbx,nby)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby
+ real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ end subroutine
+ module subroutine bocoTy_2d_gh &
+ (this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+ real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine bocoT_3d_g1 &
+ (this,W,km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz,Fimax_in,Fjmax_in)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km3_in,im_in,jm_in,Lm_in,nbx,nby,nbz
+ real(r_kind), dimension(km3_in,1-nbx:im_in+nbx,1-nby:jm_in+nby,1-nbz:Lm_in+nbz),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine bocoT_3d_gh &
+ (this,W,km_in,im_in,jm_in,Lm_in,nbx,nby,nbz,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,Lm_in,nbx,nby,nbz,mygen_min,mygen_max
+ real(r_kind), dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby,1-nbz:Lm_in+nbz),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine bocox_2d_gh &
+ (this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+ real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine bocox_2d_g1 &
+ (this,W,km_in,im_in,jm_in,nbx,nby)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby
+ real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ end subroutine
+ module subroutine bocoy_2d_g1 &
+ (this,W,km_in,im_in,jm_in,nbx,nby)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby
+ real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ end subroutine
+ module subroutine bocoy_2d_gh &
+ (this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,mygen_min,mygen_max)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,mygen_min,mygen_max
+ real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine upsend_all_g1 &
+ (this,Harray,Warray,km_in)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in
+ real(r_kind), dimension(km_in,1:this%imL,1:this%jmL),intent(in):: Harray
+ real(r_kind), dimension(km_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: Warray
+ end subroutine
+ module subroutine upsend_all_gh &
+ (this,Harray,Warray,km_in,mygen_dn,mygen_up)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in
+ real(r_kind), dimension(km_in,1:this%imL,1:this%jmL),intent(in):: Harray
+ real(r_kind), dimension(km_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: Warray
+ integer(i_kind),intent(in):: mygen_dn,mygen_up
+ end subroutine
+ module subroutine downsend_all_gh &
+ (this,Warray,Harray,km_in,mygen_up,mygen_dn)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in
+ real(r_kind), dimension(km_in,1:this%im,1:this%jm),intent(in):: Warray
+ real(r_kind), dimension(km_in,1:this%imL,1:this%jmL),intent(out):: Harray
+ integer, intent(in):: mygen_up,mygen_dn
+ end subroutine
+ module subroutine downsend_all_g2 &
+ (this,Warray,Harray,km_in)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in
+ real(r_kind), dimension(km_in,1:this%im,1:this%jm),intent(in):: Warray
+ real(r_kind), dimension(km_in,1:this%imL,1:this%jmL),intent(out):: Harray
+ end subroutine
+ module subroutine boco_2d_loc &
+ (this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,g)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,g
+ real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine bocoT_2d_loc &
+ (this,W,km_in,im_in,jm_in,nbx,nby,Fimax_in,Fjmax_in,g)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_in,im_in,jm_in,nbx,nby,g
+ real(r_kind),dimension(km_in,1-nbx:im_in+nbx,1-nby:jm_in+nby),intent(inout):: W
+ integer(i_kind), dimension(this%gm), intent(in):: Fimax_in,Fjmax_in
+ end subroutine
+ module subroutine upsend_loc_g12 &
+ (this,V_in,H,km_4_in,flag)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_4_in,flag
+ real(r_kind), dimension(km_4_in,1:this%imL,1:this%jmL),intent(in):: V_in
+ real(r_kind), dimension(km_4_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ end subroutine
+ module subroutine upsend_loc_g23 &
+ (this,V_in,H,km_16_in,flag)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_16_in,flag
+ real(r_kind), dimension(km_16_in,1:this%imL,1:this%jmL),intent(in):: V_in
+ real(r_kind), dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ end subroutine
+ module subroutine upsend_loc_g34 &
+ (this,V_in,H,km_64_in,flag)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_64_in,flag
+ real(r_kind), dimension(km_64_in,1:this%imL,1:this%jmL),intent(in):: V_in
+ real(r_kind), dimension(km_64_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ end subroutine
+ module subroutine downsend_loc_g43 &
+ (this,W,Z,km_64_in,flag)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_64_in,flag
+ real(r_kind), dimension(km_64_in,1:this%im,1:this%jm),intent(in):: W
+ real(r_kind), dimension(km_64_in,1:this%imL,1:this%jmL),intent(out):: Z
+ end subroutine
+ module subroutine downsend_loc_g32 &
+ (this,Z,H,km_16_in,flag)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_16_in,flag
+ real(r_kind), dimension(km_16_in,1:this%im,1:this%jm),intent(in):: Z
+ real(r_kind), dimension(km_16_in,1:this%imL,1:this%jmL),intent(out):: H
+ end subroutine
+ module subroutine downsend_loc_g21 &
+ (this,H,V_out,km_4_in,flag)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind), intent(in):: km_4_in,flag
+ real(r_kind), dimension(km_4_in,1:this%im,1:this%jm),intent(in):: H
+ real(r_kind), dimension(km_4_in,1:this%imL,1:this%jmL),intent(out):: V_out
+ end subroutine
+!from mg_generations.f90
+ module subroutine upsending_all &
+ (this,V,H,lquart)
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ logical, intent(in):: lquart
+ end subroutine
+ module subroutine downsending_all &
+ (this,H,V,lquart)
+ implicit none
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ logical, intent(in):: lquart
+ end subroutine
+ module subroutine weighting_all &
+ (this,V,H,lhelm)
+ implicit none
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ logical, intent(in):: lhelm
+ end subroutine
+ module subroutine upsending &
+ (this,V,H)
+ implicit none
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ real(r_kind),dimension(this%km,-1:this%imL+2,-1:this%jmL+2):: V_INT
+ real(r_kind),dimension(this%km,-1:this%imL+2,-1:this%jmL+2):: H_INT
+ end subroutine
+ module subroutine downsending &
+ (this,H,V)
+ implicit none
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ end subroutine
+ module subroutine upsending2 &
+ (this,V,H)
+ implicit none
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ end subroutine
+ module subroutine downsending2 &
+ (this,H,V)
+ implicit none
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ end subroutine
+ module subroutine upsending_highest &
+ (this,V,H)
+ implicit none
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ end subroutine
+ module subroutine downsending_highest &
+ (this,H,V)
+ implicit none
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ end subroutine
+ module subroutine upsending_ens &
+ (this,V,H,kmx)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind), intent(in):: kmx
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ end subroutine
+ module subroutine downsending_ens &
+ (this,H,V,kmx)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind), intent(in):: kmx
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ end subroutine
+ module subroutine upsending2_ens &
+ (this,V,H,kmx)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind), intent(in):: kmx
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ end subroutine
+ module subroutine downsending2_ens &
+ (this,H,V,kmx)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind), intent(in):: kmx
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ end subroutine
+ module subroutine upsending_ens_nearest &
+ (this,V,H,kmx)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind), intent(in):: kmx
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ end subroutine
+ module subroutine downsending_ens_nearest &
+ (this,H,V,kmx)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind), intent(in):: kmx
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ end subroutine
+ module subroutine upsending_loc_g3 &
+ (this,V,H,Z,km_in,km_4_in,km_16_in)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: km_in,km_4_in,km_16_in
+ real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+ real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: Z
+ end subroutine
+ module subroutine upsending_loc_g4 &
+ (this,V,H,Z,W,km_in,km_4_in,km_16_in,km_64_in)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: km_in,km_4_in,km_16_in,km_64_in
+ real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(in):: V
+ real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: H
+ real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: Z
+ real(r_kind),dimension(km_64_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(out):: W
+ end subroutine
+ module subroutine downsending_loc_g3 &
+ (this,Z,H,V,km_in,km_4_in,km_16_in)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: km_in,km_4_in,km_16_in
+ real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: Z
+ real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ end subroutine
+ module subroutine downsending_loc_g4 &
+ (this,W,Z,H,V,km_in,km_4_in,km_16_in,km_64_in)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: km_in,km_4_in,km_16_in,km_64_in
+ real(r_kind),dimension(km_64_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: W
+ real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: Z
+ real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ end subroutine
+ module subroutine weighting_helm &
+ (this,V,H)
+ implicit none
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ end subroutine
+ module subroutine weighting &
+ (this,V,H)
+ implicit none
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ end subroutine
+ module subroutine weighting_highest &
+ (this,H)
+ implicit none
+ class (mg_intstate_type),target:: this
+ real(r_kind),dimension(this%km,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ end subroutine
+ module subroutine weighting_ens &
+ (this,V,H,kmx)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: kmx
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ real(r_kind),dimension(kmx,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H
+ end subroutine
+ module subroutine weighting_loc_g3 &
+ (this,V,H04,H16,km_in,km_4_in,km_16_in)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: km_in,km_4_in,km_16_in
+ real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H04
+ real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H16
+ end subroutine
+ module subroutine weighting_loc_g4 &
+ (this,V,H04,H16,H64,km_in,km_4_in,km_16_in,km_64_in)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: km_in,km_4_in,km_16_in,km_64_in
+ real(r_kind),dimension(km_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: V
+ real(r_kind),dimension(km_4_in ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H04
+ real(r_kind),dimension(km_16_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H16
+ real(r_kind),dimension(km_64_in,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy),intent(inout):: H64
+ end subroutine
+ module subroutine adjoint &
+ (this,F,W,km_in,g)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: g
+ integer(i_kind),intent(in):: km_in
+ real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(in):: F
+ real(r_kind), dimension(km_in,-1:this%imL+2,-1:this%jmL+2), intent(out):: W
+ end subroutine
+ module subroutine direct1 &
+ (this,W,F,km_in,g)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: g
+ integer(i_kind),intent(in):: km_in
+ real(r_kind), dimension(km_in,-1:this%imL+2,-1:this%jmL+2), intent(in):: W
+ real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(out):: F
+ end subroutine
+ module subroutine adjoint2 &
+ (this,F,W,km_in,g)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: g
+ integer(i_kind),intent(in):: km_in
+ real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(in):: F
+ real(r_kind), dimension(km_in,0:this%imL+1,0:this%jmL+1), intent(out):: W
+ end subroutine
+ module subroutine direct2 &
+ (this,W,F,km_in,g)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: g
+ integer(i_kind),intent(in):: km_in
+ real(r_kind), dimension(km_in,0:this%imL+1,0:this%jmL+1), intent(in):: W
+ real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(out):: F
+ end subroutine
+ module subroutine adjoint_nearest &
+ (this,F,W,km_in,g)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: g
+ integer(i_kind),intent(in):: km_in
+ real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(in):: F
+ real(r_kind), dimension(km_in,-1:this%imL+2,-1:this%jmL+2), intent(out):: W
+ end subroutine
+ module subroutine direct_nearest &
+ (this,W,F,km_in,g)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: g
+ integer(i_kind),intent(in):: km_in
+ real(r_kind), dimension(km_in,-1:this%imL+2,-1:this%jmL+2), intent(in):: W
+ real(r_kind), dimension(km_in,1:this%im,1:this%jm), intent(out):: F
+ end subroutine
+ module subroutine adjoint_highest &
+ (this,F,W,km_in,g)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: g
+ integer(i_kind),intent(in):: km_in
+ real(r_kind), dimension(km_in,1:this%im0(g),1:this%jm0(g)), intent(in):: F
+ real(r_kind), dimension(km_in,-1:this%im0(g+1)+2,-1:this%jm0(g+1)+2), intent(out):: W
+ end subroutine
+ module subroutine direct_highest &
+ (this,W,F,km_in,g)
+ implicit none
+ class (mg_intstate_type),target:: this
+ integer(i_kind),intent(in):: g
+ integer(i_kind),intent(in):: km_in
+ real(r_kind), dimension(km_in,-1:this%im0(g+1)+2,-1:this%jm0(g+1)+2), intent(in):: W
+ real(r_kind), dimension(km_in,1:this%im0(g),1:this%jm0(g)), intent(out):: F
+ end subroutine
+!from mg_filtering
+ module subroutine filtering_procedure(this,mg_filt,mg_filt_flag)
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: mg_filt
+ integer(i_kind),intent(in):: mg_filt_flag
+ end subroutine
+ module subroutine filtering_rad3(this)
+ class(mg_intstate_type),target::this
+ end subroutine
+ module subroutine filtering_lin3(this)
+ class(mg_intstate_type),target::this
+ end subroutine
+ module subroutine filtering_rad2_bkg(this)
+ class(mg_intstate_type),target::this
+ end subroutine
+ module subroutine filtering_lin2_bkg(this)
+ class(mg_intstate_type),target::this
+ end subroutine
+ module subroutine filtering_fast_bkg(this)
+ class(mg_intstate_type),target::this
+ end subroutine
+ module subroutine filtering_rad2_ens(this,mg_filt_flag)
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: mg_filt_flag
+ end subroutine
+ module subroutine filtering_lin2_ens(this,mg_filt_flag)
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: mg_filt_flag
+ end subroutine
+ module subroutine filtering_fast_ens(this,mg_filt_flag)
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: mg_filt_flag
+ end subroutine
+ module subroutine filtering_rad_highest(this)
+ class(mg_intstate_type),target::this
+ end subroutine
+ module subroutine sup_vrbeta1 &
+ (this,kmax,hx,hy,hz,im,jm,lm, pasp,ss, V)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: kmax,hx,hy,hz,im,jm,lm
+ real(r_kind),dimension(1:kmax,1-hx:im+hx,1-hy:jm+hy,1:lm),intent(inout):: V
+ real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+ real(r_kind),dimension(1:lm), intent(in):: ss
+ end subroutine
+ module subroutine sup_vrbeta1T &
+ (this,kmax,hx,hy,hz,im,jm,lm, pasp,ss, V)
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: kmax,hx,hy,hz,im,jm,lm
+ real(r_kind),dimension(1:kmax,1-hx:im+hx,1-hy:jm+hy,1:lm),intent(inout):: V
+ real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+ real(r_kind),dimension(1:lm), intent(in):: ss
+ end subroutine
+ module subroutine sup_vrbeta3 &
+ (this,kmax,hx,hy,hz,im,jm,lm, pasp,ss, V)
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: kmax,hx,hy,hz,im,jm,lm
+ real(r_kind),dimension(1:kmax,1-hx:im+hx,1-hy:jm+hy,1:lm),intent(inout):: V
+ real(r_kind),dimension(3,3,1:im,1:jm,1:lm), intent(in):: pasp
+ real(r_kind),dimension(1:im,1:jm,1:lm), intent(in):: ss
+ end subroutine
+ module subroutine sup_vrbeta3T &
+ (this,kmax,hx,hy,hz,im,jm,lm, pasp,ss,V)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: kmax,hx,hy,hz,im,jm,lm
+ real(r_kind),dimension(1:kmax,1-hx:im+hx,1-hy:jm+hy,1:lm),intent(inout):: V
+ real(r_kind),dimension(3,3,1:im,1:jm,1:lm), intent(in):: pasp
+ real(r_kind),dimension(1:im,1:jm,1:lm), intent(in):: ss
+ end subroutine
+ module subroutine sup_vrbeta1_ens &
+ (this,km_en,hx,hy,hz,im,jm,lm,pasp,ss,VALL)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: km_en,hx,hy,hz,im,jm,lm
+ real(r_kind),dimension(1:km_en*lm,1-hx:im+hx,1-hy:jm+hy),intent(inout):: VALL
+ real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+ real(r_kind),dimension(1:lm), intent(in):: ss
+ end subroutine
+ module subroutine sup_vrbeta1T_ens &
+ (this,km_en,hx,hy,hz,im,jm,lm,pasp,ss,VALL)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: km_en,hx,hy,hz,im,jm,lm
+ real(r_kind),dimension(1:km_en*lm,1-hx:im+hx,1-hy:jm+hy),intent(inout):: VALL
+ real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+ real(r_kind),dimension(1:lm), intent(in):: ss
+ end subroutine
+ module subroutine sup_vrbeta1_bkg &
+ (this,km,km3,hx,hy,hz,im,jm,lm,pasp,ss,VALL)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: km,km3,hx,hy,hz,im,jm,lm
+ real(r_kind),dimension(1:km,1-hx:im+hx,1-hy:jm+hy),intent(inout):: VALL
+ real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+ real(r_kind),dimension(1:lm), intent(in):: ss
+ end subroutine
+ module subroutine sup_vrbeta1T_bkg &
+ (this,km,km3,hx,hy,hz,im,jm,lm,pasp,ss,VALL)
+ implicit none
+ class(mg_intstate_type),target::this
+ integer(i_kind),intent(in):: km,km3,hx,hy,hz,im,jm,lm
+ real(r_kind),dimension(1:km,1-hx:im+hx,1-hy:jm+hy),intent(inout):: VALL
+ real(r_kind),dimension(1,1,1:lm), intent(in):: pasp
+ real(r_kind),dimension(1:lm), intent(in):: ss
+ end subroutine
+!from mg_transfer.f90
+ module subroutine anal_to_filt_allmap(this,WORKA)
+ class(mg_intstate_type),target::this
+ real (r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+ end subroutine
+ module subroutine filt_to_anal_allmap(this,WORKA)
+ class(mg_intstate_type),target::this
+ real (r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+ end subroutine
+ module subroutine anal_to_filt_all(this,WORKA)
+ class(mg_intstate_type),target::this
+ real (r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+ end subroutine
+ module subroutine filt_to_anal_all(this,WORKA)
+ class(mg_intstate_type),target::this
+ real (r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+ end subroutine
+ module subroutine anal_to_filt_all2(this,WORKA)
+ class(mg_intstate_type),target::this
+ real (r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+ end subroutine
+ module subroutine filt_to_anal_all2(this,WORKA)
+ class(mg_intstate_type),target::this
+ real (r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+ end subroutine
+ module subroutine stack_to_composite(this,ARR_ALL,A2D,A3D)
+ class(mg_intstate_type),target::this
+ real(r_kind),dimension(this%km ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy), intent(in):: ARR_ALL
+ real(r_kind),dimension(this%km3,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy,this%lm),intent(out):: A3D
+ real(r_kind),dimension(this%km2,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy) ,intent(out):: A2D
+ end subroutine
+ module subroutine composite_to_stack(this,A2D,A3D,ARR_ALL)
+ class(mg_intstate_type),target::this
+ real(r_kind),dimension(this%km2,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy), intent(in):: A2D
+ real(r_kind),dimension(this%km3,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy,this%lm),intent(in):: A3D
+ real(r_kind),dimension(this%km ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy), intent(out):: ARR_ALL
+ end subroutine
+ module subroutine S2C_ens(this,ARR_ALL,A3D,imn,imx,jmn,jmx,lmx,kmx,kmx_all)
+ class(mg_intstate_type),target::this
+ integer, intent(in):: imn,imx,jmn,jmx,lmx,kmx,kmx_all
+ real(r_kind),dimension(kmx_all,imn:imx,jmn:jmx) ,intent(in):: ARR_ALL
+ real(r_kind),dimension(this%km3_all,imn:imx,jmn:jmx,lmx),intent(out):: A3D
+ end subroutine
+ module subroutine C2S_ens(this,A3D,ARR_ALL,imn,imx,jmn,jmx,lmx,kmx,kmx_all)
+ class(mg_intstate_type),target::this
+ integer, intent(in):: imn,imx,jmn,jmx,lmx,kmx,kmx_all
+ real(r_kind),dimension(this%km3_all,imn:imx,jmn:jmx,lmx),intent(in):: A3D
+ real(r_kind),dimension(kmx_all,imn:imx,jmn:jmx) ,intent(out):: ARR_ALL
+ end subroutine
+ module subroutine anal_to_filt(this,WORK)
+ class(mg_intstate_type),target::this
+ real (r_kind):: WORK(this%km_all,1:this%nm,1:this%mm)
+ end subroutine
+ module subroutine filt_to_anal(this,WORK)
+ class(mg_intstate_type),target::this
+ real (r_kind):: WORK(this%km_all,1:this%nm,1:this%mm)
+ end subroutine
+!from mg_entrymod.f90
+ module subroutine mg_initialize(this,inputfilename,obj_parameter)
+ class (mg_intstate_type):: this
+ character*(*),optional,intent(in) :: inputfilename
+ class(mg_parameter_type),optional,intent(in)::obj_parameter
+ end subroutine
+ module subroutine mg_finalize(this)
+ implicit none
+ class (mg_intstate_type)::this
+ end subroutine
+end interface
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+contains
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+subroutine allocate_mg_intstate(this)
+!***********************************************************************
+! !
+! Allocate internal state variables !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+
+if(this%l_loc) then
+ allocate(this%w1_loc(this%km_all ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%w1_loc=0.
+ allocate(this%w2_loc(this%km_all/4 ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%w2_loc=0.
+ allocate(this%w3_loc(this%km_all/16,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%w3_loc=0.
+ allocate(this%w4_loc(this%km_all/64,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%w4_loc=0.
+endif
+
+allocate(this%V(1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy,this%lm)) ; this%V=0.
+allocate(this%VALL(this%km_all,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%VALL=0.
+allocate(this%HALL(this%km_all,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%HALL=0.
+
+allocate(this%a_diff_f(this%km_all,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%a_diff_f=0.
+allocate(this%a_diff_h(this%km_all,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%a_diff_h=0.
+allocate(this%b_diff_f(this%km_all,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%b_diff_f=0.
+allocate(this%b_diff_h(this%km_all,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%b_diff_h=0.
+
+allocate(this%p_eps(1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%p_eps=0.
+allocate(this%p_del(1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%p_del=0.
+allocate(this%p_sig(1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%p_sig=0.
+allocate(this%p_rho(1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy)) ; this%p_rho=0.
+
+allocate(this%paspx(1,1,1:this%im)) ; this%paspx=0.
+allocate(this%paspy(1,1,1:this%jm)) ; this%paspy=0.
+
+allocate(this%pasp1(1,1,1:this%lm)) ; this%pasp1=0.
+allocate(this%pasp2(2,2,1:this%im,1:this%jm)) ; this%pasp2=0.
+allocate(this%pasp3(3,3,1:this%im,1:this%jm,1:this%lm)) ; this%pasp3=0.
+
+allocate(this%vpasp2(0:2,1:this%im,1:this%jm)) ; this%vpasp2=0.
+allocate(this%hss2(1:this%im,1:this%jm,1:3)) ; this%hss2=0.
+
+allocate(this%vpasp3(1:6,1:this%im,1:this%jm,1:this%lm)) ; this%vpasp3=0.
+allocate(this%hss3(1:this%im,1:this%jm,1:this%lm,1:6)) ; this%hss3=0.
+
+allocate(this%ssx(1:this%im)) ; this%ssx=0.
+allocate(this%ssy(1:this%jm)) ; this%ssy=0.
+allocate(this%ss1(1:this%lm)) ; this%ss1=0.
+allocate(this%ss2(1:this%im,1:this%jm)) ; this%ss2=0.
+allocate(this%ss3(1:this%im,1:this%jm,1:this%lm)) ; this%ss3=0.
+
+allocate(this%dixs(1:this%im,1:this%jm,3)) ; this%dixs=0
+allocate(this%diys(1:this%im,1:this%jm,3)) ; this%diys=0
+
+allocate(this%dixs3(1:this%im,1:this%jm,1:this%lm,6)) ; this%dixs3=0
+allocate(this%diys3(1:this%im,1:this%jm,1:this%lm,6)) ; this%diys3=0
+allocate(this%dizs3(1:this%im,1:this%jm,1:this%lm,6)) ; this%dizs3=0
+
+allocate(this%qcols(0:7,1:this%im,1:this%jm,1:this%lm)) ; this%qcols=0
+
+!
+! for re-decomposition
+!
+
+allocate(this%iref(1:this%nm)) ; this%iref=0
+allocate(this%jref(1:this%mm)) ; this%jref=0
+
+allocate(this%irefq(1:this%nm)) ; this%irefq=0
+allocate(this%jrefq(1:this%mm)) ; this%jrefq=0
+
+allocate(this%irefL(1:this%nm)) ; this%irefL=0
+allocate(this%jrefL(1:this%mm)) ; this%jrefL=0
+
+allocate(this%cx0(1:this%nm)) ; this%cx0=0.
+allocate(this%cx1(1:this%nm)) ; this%cx1=0.
+allocate(this%cx2(1:this%nm)) ; this%cx2=0.
+allocate(this%cx3(1:this%nm)) ; this%cx3=0.
+
+allocate(this%cy0(1:this%mm)) ; this%cy0=0.
+allocate(this%cy1(1:this%mm)) ; this%cy1=0.
+allocate(this%cy2(1:this%mm)) ; this%cy2=0.
+allocate(this%cy3(1:this%mm)) ; this%cy3=0.
+
+allocate(this%qx0(1:this%nm)) ; this%qx0=0.
+allocate(this%qx1(1:this%nm)) ; this%qx1=0.
+allocate(this%qx2(1:this%nm)) ; this%qx2=0.
+
+allocate(this%qy0(1:this%mm)) ; this%qy0=0.
+allocate(this%qy1(1:this%mm)) ; this%qy1=0.
+allocate(this%qy2(1:this%mm)) ; this%qy2=0.
+
+allocate(this%Lx0(1:this%nm)) ; this%Lx0=0.
+allocate(this%Lx1(1:this%nm)) ; this%Lx1=0.
+
+allocate(this%Ly0(1:this%mm)) ; this%Ly0=0.
+allocate(this%Ly1(1:this%mm)) ; this%Ly1=0.
+
+allocate(this%p_coef(4)) ; this%p_coef=0.
+allocate(this%q_coef(4)) ; this%q_coef=0.
+
+allocate(this%a_coef(3)) ; this%a_coef=0.
+allocate(this%b_coef(3)) ; this%b_coef=0.
+
+allocate(this%cf00(1:this%nm,1:this%mm)) ; this%cf00=0.
+allocate(this%cf01(1:this%nm,1:this%mm)) ; this%cf01=0.
+allocate(this%cf02(1:this%nm,1:this%mm)) ; this%cf02=0.
+allocate(this%cf03(1:this%nm,1:this%mm)) ; this%cf03=0.
+allocate(this%cf10(1:this%nm,1:this%mm)) ; this%cf10=0.
+allocate(this%cf11(1:this%nm,1:this%mm)) ; this%cf11=0.
+allocate(this%cf12(1:this%nm,1:this%mm)) ; this%cf12=0.
+allocate(this%cf13(1:this%nm,1:this%mm)) ; this%cf13=0.
+allocate(this%cf20(1:this%nm,1:this%mm)) ; this%cf20=0.
+allocate(this%cf21(1:this%nm,1:this%mm)) ; this%cf21=0.
+allocate(this%cf22(1:this%nm,1:this%mm)) ; this%cf22=0.
+allocate(this%cf23(1:this%nm,1:this%mm)) ; this%cf23=0.
+allocate(this%cf30(1:this%nm,1:this%mm)) ; this%cf30=0.
+allocate(this%cf31(1:this%nm,1:this%mm)) ; this%cf31=0.
+allocate(this%cf32(1:this%nm,1:this%mm)) ; this%cf32=0.
+allocate(this%cf33(1:this%nm,1:this%mm)) ; this%cf33=0.
+
+allocate(this%Lref(1:this%lm_a)) ; this%Lref=0
+allocate(this%Lref_h(1:this%lm)) ; this%Lref_h=0
+
+allocate(this%cvf1(1:this%lm_a)) ; this%cvf1=0.
+allocate(this%cvf2(1:this%lm_a)) ; this%cvf2=0.
+allocate(this%cvf3(1:this%lm_a)) ; this%cvf3=0.
+allocate(this%cvf4(1:this%lm_a)) ; this%cvf4=0.
+
+allocate(this%cvh1(1:this%lm)) ; this%cvh1=0.
+allocate(this%cvh2(1:this%lm)) ; this%cvh2=0.
+allocate(this%cvh3(1:this%lm)) ; this%cvh3=0.
+allocate(this%cvh4(1:this%lm)) ; this%cvh4=0.
+
+!-----------------------------------------------------------------------
+endsubroutine allocate_mg_intstate
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+subroutine def_mg_weights(this)
+!***********************************************************************
+! !
+! Define weights and scales !
+! !
+implicit none
+class (mg_intstate_type),target::this
+!***********************************************************************
+integer(i_kind):: i,j,L
+real(r_kind):: gen_fac
+!-----------------------------------------------------------------------
+
+this%p_eps(:,:)=0.0
+this%p_del(:,:)=0.0
+this%p_sig(:,:)=0.0
+this%p_rho(:,:)=0.0
+
+!--------------------------------------------------------
+!
+! For localization (for now)
+!
+if(this%l_loc) then
+ this%w1_loc(:,:,:)=this%mg_weig1
+ this%w2_loc(:,:,:)=this%mg_weig2
+ this%w3_loc(:,:,:)=this%mg_weig3
+ this%w4_loc(:,:,:)=this%mg_weig4
+endif
+!--------------------------------------------------------
+gen_fac=1.
+this%a_diff_f(:,:,:)=this%mg_weig1
+this%a_diff_h(:,:,:)=this%mg_weig1
+
+this%b_diff_f(:,:,:)=0.
+this%b_diff_h(:,:,:)=0.
+
+select case(this%my_hgen)
+case(2)
+ this%a_diff_h(:,:,:)=this%mg_weig2
+case(3)
+ this%a_diff_h(:,:,:)=this%mg_weig3
+case default
+ this%a_diff_h(:,:,:)=this%mg_weig4
+end select
+
+do L=1,this%lm
+ this%pasp1(1,1,L)=this%pasp01
+enddo
+
+do i=1,this%im
+ this%paspx(1,1,i)=this%pasp02
+enddo
+do j=1,this%jm
+ this%paspy(1,1,j)=this%pasp02
+enddo
+
+do j=1,this%jm
+do i=1,this%im
+ this%pasp2(1,1,i,j)=this%pasp02*(1.+this%p_del(i,j))
+ this%pasp2(2,2,i,j)=this%pasp02*(1.-this%p_del(i,j))
+ this%pasp2(1,2,i,j)=this%pasp02*this%p_eps(i,j)
+ this%pasp2(2,1,i,j)=this%pasp02*this%p_eps(i,j)
+end do
+end do
+
+do L=1,this%lm
+ do j=1,this%jm
+ do i=1,this%im
+ this%pasp3(1,1,i,j,l)=this%pasp03*(1+this%p_del(i,j))
+ this%pasp3(2,2,i,j,l)=this%pasp03
+ this%pasp3(3,3,i,j,l)=this%pasp03*(1-this%p_del(i,j))
+ this%pasp3(1,2,i,j,l)=this%pasp03*this%p_eps(i,j)
+ this%pasp3(2,1,i,j,l)=this%pasp03*this%p_eps(i,j)
+ this%pasp3(2,3,i,j,l)=this%pasp03*this%p_sig(i,j)
+ this%pasp3(3,2,i,j,l)=this%pasp03*this%p_sig(i,j)
+ this%pasp3(1,3,i,j,l)=this%pasp03*this%p_rho(i,j)
+ this%pasp3(3,1,i,j,l)=this%pasp03*this%p_rho(i,j)
+ end do
+ end do
+end do
+
+
+if(.not.this%mgbf_line) then
+ if(this%nxm*this%nym>1) then
+ if(this%l_loc) then
+ if(this%l_vertical_filter) then
+ call this%cholaspect(1,this%lm,this%pasp1)
+ call this%getlinesum(this%hz,1,this%lm,this%pasp1,this%ss1)
+ do L=1,this%lm
+ this%VALL(L,2,1)=1.
+ call this%sup_vrbeta1T_ens(1,0,0,this%hz,1,1,this%lm,this%pasp1,this%ss1,this%VALL(1:this%lm,2,1))
+ call this%sup_vrbeta1_ens(1,0,0,this%hz,1,1,this%lm,this%pasp1,this%ss1,this%VALL(1:this%lm,2,1))
+ this%VALL(L,1,1)=sqrt(this%VALL(L,2,1))
+ this%VALL(1:this%lm,2,1)=0.
+ enddo
+ this%ss1(1:this%lm)=this%ss1(1:this%lm)/this%VALL(1:this%lm,1,1)
+ this%VALL(1:this%lm,1,1)=0.
+ endif
+ call this%cholaspect(1,this%im,1,this%jm,this%pasp2)
+ call this%getlinesum(this%hx,1,this%im,this%hy,1,this%jm,this%pasp2,this%ss2)
+ this%VALL(1,this%im/2,this%jm/2)=1.
+ call this%rbetaT(this%hx,1,this%im,this%hy,1,this%jm,this%pasp2,this%ss2,this%VALL(1,:,:))
+ call this%rbeta(this%hx,1,this%im,this%hy,1,this%jm,this%pasp2,this%ss2,this%VALL(1,:,:))
+ this%ss2=this%ss2/sqrt(this%VALL(1,this%im/2,this%jm/2))
+ this%VALL(1,:,:)=0.
+ call this%cholaspect(1,this%im,this%paspx)
+ call this%getlinesum(this%hx,1,this%im,this%paspx,this%ssx)
+ this%VALL(1,this%im/2,1)=1.
+ call this%rbetaT(this%hx,1,this%im,this%paspx,this%ssx,this%VALL(1,:,1))
+ call this%rbeta(this%hx,1,this%im,this%paspx(1,1,:),this%ssx,this%VALL(1,:,1))
+ this%ssx=this%ssx/sqrt(this%VALL(1,this%im/2,1))
+ this%VALL(1,:,1)=0.
+ call this%cholaspect(1,this%jm,this%paspy)
+ call this%getlinesum(this%hy,1,this%jm,this%paspy,this%ssy)
+ this%VALL(1,1,this%jm/2)=1.
+ call this%rbetaT(this%hy,1,this%jm,this%paspy,this%ssy,this%VALL(1,1,:))
+ call this%rbeta(this%hy,1,this%jm,this%paspy(1,1,:),this%ssy,this%VALL(1,1,:))
+ this%ssy=this%ssy/sqrt(this%VALL(1,1,this%jm/2))
+ this%VALL(1,1,:)=0.
+ else
+ call this%cholaspect(1,this%lm,this%pasp1)
+ call this%cholaspect(1,this%im,1,this%jm,this%pasp2)
+ call this%cholaspect(1,this%im,1,this%jm,1,this%lm,this%pasp3)
+ call this%getlinesum(this%hx,1,this%im,this%paspx,this%ssx)
+ call this%getlinesum(this%hy,1,this%jm,this%paspy,this%ssy)
+ call this%getlinesum(this%hz,1,this%lm,this%pasp1,this%ss1)
+ call this%getlinesum(this%hx,1,this%im,this%hy,1,this%jm,this%pasp2,this%ss2)
+ call this%getlinesum(this%hx,1,this%im,this%hy,1,this%jm,this%hz,1,this%lm,this%pasp3,this%ss3)
+ end if
+ else
+ call this%cholaspect(1,this%imH,1,this%jmH,&
+ &this%pasp2(:,:,1:this%imH,1:this%jmH))
+ call this%getlinesum(this%hx,1,this%imH,this%hy,1,this%jmH,&
+ &this%pasp2(:,:,1:this%imH,1:this%jmH),this%ss2(1:this%imH,1:this%jmH))
+ this%VALL(1,this%imH/2,this%jmH/2)=1.
+ call this%rbetaT(this%hx,1,this%imH,this%hy,1,this%jmH,&
+ &this%pasp2(:,:,1:this%imH,1:this%jmH),this%ss2(1:this%imH,1:this%jmH),&
+ &this%VALL(1,1-this%hx:this%imH+this%hx,1-this%hy:this%jmH+this%hy))
+ call this%rbeta(this%hx,1,this%imH,this%hy,1,this%jmH,&
+ &this%pasp2(:,:,1:this%imH,1:this%jmH),this%ss2(1:this%imH,1:this%jmH),&
+ &this%VALL(1,1-this%hx:this%imH+this%hx,1-this%hy:this%jmH+this%hy))
+ this%ss2=this%ss2/sqrt(this%VALL(1,this%imH/2,this%jmH/2))
+ this%VALL(1,1-this%hx:this%imH+this%hx,1-this%hy:this%jmH+this%hy)=0.
+ end if
+end if
+!-----------------------------------------------------------------------
+endsubroutine def_mg_weights
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+subroutine init_mg_line(this)
+implicit none
+class(mg_intstate_type),target::this
+integer(i_kind):: i,j,L,icol
+logical:: ff
+!***********************************************************************
+! !
+! Inititate line filters !
+! !
+!***********************************************************************
+!-----------------------------------------------------------------------
+
+do j=1,this%jm
+do i=1,this%im
+ call t22_to_3(this%pasp2(:,:,i,j),this%vpasp2(:,i,j))
+enddo
+enddo
+
+do l=1,this%lm
+do j=1,this%jm
+do i=1,this%im
+ call t33_to_6(this%pasp3(:,:,i,j,l),this%vpasp3(:,i,j,l))
+enddo
+enddo
+enddo
+
+call inimomtab(this%p,this%nh,ff)
+
+call tritform(1,this%im,1,this%jm,this%vpasp2, this%dixs,this%diys, ff)
+
+do icol=1,3
+ this%hss2(:,:,icol)=this%vpasp2(icol-1,:,:)
+enddo
+
+call hextform(1,this%im,1,this%jm,1,this%lm,this%vpasp3,this%qcols,this%dixs3,this%diys3,this%dizs3, ff)
+
+do icol=1,6
+ this%hss3(:,:,:,icol)=this%vpasp3(icol,:,:,:)
+enddo
+
+!-----------------------------------------------------------------------
+endsubroutine init_mg_line
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+subroutine deallocate_mg_intstate(this)
+implicit none
+class (mg_intstate_type),target:: this
+!***********************************************************************
+! !
+! Deallocate internal state variables !
+! !
+!***********************************************************************
+
+deallocate(this%V)
+
+deallocate(this%HALL,this%VALL)
+
+deallocate(this%a_diff_f,this%b_diff_f)
+deallocate(this%a_diff_h,this%b_diff_h)
+deallocate(this%p_eps,this%p_del,this%p_sig,this%p_rho,this%pasp1,this%pasp2,this%pasp3,this%ss1,this%ss2,this%ss3)
+deallocate(this%dixs,this%diys)
+deallocate(this%dixs3,this%diys3,this%dizs3)
+deallocate(this%qcols)
+
+!
+! for re-decomposition
+!
+deallocate(this%iref,this%jref)
+deallocate(this%irefq,this%jrefq)
+deallocate(this%irefL,this%jrefL)
+
+deallocate(this%cf00,this%cf01,this%cf02,this%cf03,this%cf10,this%cf11,this%cf12,this%cf13)
+deallocate(this%cf20,this%cf21,this%cf22,this%cf23,this%cf30,this%cf31,this%cf32,this%cf33)
+
+deallocate(this%Lref,this%Lref_h)
+
+deallocate(this%cvf1,this%cvf2,this%cvf3,this%cvf4)
+
+deallocate(this%cvh1,this%cvh2,this%cvh3,this%cvh4)
+
+deallocate(this%cx0,this%cx1,this%cx2,this%cx3)
+deallocate(this%cy0,this%cy1,this%cy2,this%cy3)
+
+deallocate(this%qx0,this%qx1,this%qx2)
+deallocate(this%qy0,this%qy1,this%qy2)
+
+deallocate(this%Lx0,this%Lx1)
+deallocate(this%Ly0,this%Ly1)
+
+deallocate(this%p_coef,this%q_coef)
+deallocate(this%a_coef,this%b_coef)
+
+if(this%l_loc) then
+ deallocate(this%w1_loc,this%w2_loc,this%w3_loc,this%w4_loc)
+endif
+
+end subroutine deallocate_mg_intstate
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+end module mg_intstate
diff --git a/src/mgbf/mg_mppstuff.f90 b/src/mgbf/mg_mppstuff.f90
new file mode 100644
index 0000000000..e1d24b180c
--- /dev/null
+++ b/src/mgbf/mg_mppstuff.f90
@@ -0,0 +1,190 @@
+submodule(mg_parameter) mg_mppstuff
+!$$$ submodule documentation block
+! . . . .
+! module: mg_mppstuff
+! prgmmr: rancic org: NCEP/EMC date: 2020
+!
+! abstract: Everything related to mpi communication
+!
+! module history log:
+! 2023-04-19 lei - object-oriented coding
+! 2024-01-11 rancic - optimization for ensemble localization
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! init_mg_MPI -
+! barrierMPI -
+! finishMPI -
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use kinds, only: i_kind
+implicit none
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+contains
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine init_mg_MPI(this)
+!***********************************************************************
+! !
+! Initialize mpi !
+! Create group for filter grid !
+! !
+!***********************************************************************
+use mpi
+
+implicit none
+class (mg_parameter_type),target:: this
+integer(i_kind):: g,m
+integer(i_kind), dimension(this%npes_filt):: out_ranks
+integer(i_kind):: nf
+integer(i_kind)::ierr
+integer(i_kind):: color
+include "type_parameter_locpointer.inc"
+include "type_parameter_point2this.inc"
+!-----------------------------------------------------------------------
+
+!***
+!*** Initial MPI calls
+!***
+ call MPI_COMM_RANK(MPI_COMM_WORLD,mype,ierr)
+ call MPI_COMM_SIZE(MPI_COMM_WORLD,npes,ierr)
+! call MPI_Barrier(MPI_COMM_WORLD, ierr)
+
+ ! Create a new communicator with MPI_Comm_split
+ color=1 ! just create an communicator now for the whole processes
+ call MPI_Comm_split(MPI_COMM_WORLD, color, mype, mpi_comm_comp, ierr)
+ call MPI_COMM_SIZE(mpi_comm_comp,npes,ierr)
+
+ rTYPE = MPI_REAL
+ dTYPE = MPI_DOUBLE
+ iTYPE = MPI_INTEGER
+
+!***
+!*** Analysis grid
+!***
+
+ nx = mod(mype,nxm)+1
+ my = (mype/nxm)+1
+
+!***
+!*** Define PEs that handle high generations
+!***
+
+ mype_hgen=-1
+ my_hgen=-1
+
+ if( mype < maxpe_filt-nxy(1)) then
+ mype_hgen=mype+nxy(1)
+ endif
+ do g=1,gm
+ if(maxpe_fgen(g-1)<= mype_hgen .and. mype_hgen< maxpe_fgen(g)) then
+ my_hgen=g
+ endif
+ enddo
+ l_hgen = mype_hgen >-1
+
+!***
+!*** Chars
+!***
+ write(c_mype,1000) mype
+ 1000 format(i5.5)
+
+!-----------------------------------------------------------------------
+!
+ call MPI_BARRIER(mpi_comm_comp,ierr)
+!
+!-----------------------------------------------------------------------
+!***
+!*** Define group communicator for higher generations
+!***
+!
+! Associate a group with communicator this@mpi_comm_comp
+!
+ call MPI_COMM_GROUP(mpi_comm_comp,group_world,ierr)
+!
+! Create a new group out of exising group
+!
+ do nf = 1,npes_filt
+ out_ranks(nf)=nf-1
+ enddo
+
+ call MPI_GROUP_INCL(group_world,npes_filt,out_ranks,group_work,ierr)
+!
+! Now create a new communicator associated with new group
+!
+ call MPI_COMM_CREATE(mpi_comm_comp, group_work, mpi_comm_work, ierr)
+
+ if( mype < npes_filt) then
+
+ call MPI_COMM_RANK(mpi_comm_work,mype_gr,ierr)
+ call MPI_COMM_SIZE(mpi_comm_work,npes_gr,ierr)
+
+ else
+
+ mype_gr= -1
+ npes_gr= npes_filt
+
+ endif
+
+!-----------------------------------------------------------------------
+!
+ call MPI_BARRIER(mpi_comm_comp,ierr)
+!
+!-----------------------------------------------------------------------
+endsubroutine init_mg_MPI
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine barrierMPI(this)
+!***********************************************************************
+! !
+! Call barrier for all !
+! !
+!***********************************************************************
+use mpi
+
+implicit none
+class(mg_parameter_type),target::this
+integer(i_kind):: ierr
+include "type_parameter_locpointer.inc"
+include "type_parameter_point2this.inc"
+!-----------------------------------------------------------------------
+
+ call MPI_BARRIER(mpi_comm_comp,ierr)
+
+!-----------------------------------------------------------------------
+endsubroutine barrierMPI
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine finishMPI(this)
+!***********************************************************************
+! !
+! Finalize MPI !
+! !
+!***********************************************************************
+use mpi
+
+implicit none
+class(mg_parameter_type),target::this
+!
+! don't need mpi_finalize if mgbf is a lib to be called from outside
+!
+ call MPI_FINALIZE(this%ierr)
+ stop
+!
+!-----------------------------------------------------------------------
+endsubroutine finishMPI
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+end submodule mg_mppstuff
+
diff --git a/src/mgbf/mg_parameter.f90 b/src/mgbf/mg_parameter.f90
new file mode 100644
index 0000000000..f08b87aab3
--- /dev/null
+++ b/src/mgbf/mg_parameter.f90
@@ -0,0 +1,936 @@
+module mg_parameter
+!$$$ submodule documentation block
+! . . . .
+! module: mg_parameter
+! prgmmr: rancic org: NCEP/EMC date: 2022
+!
+! abstract: Set resolution, grid and decomposition (offset version)
+!
+! module history log:
+! 2023-04-19 lei - object-oriented coding
+! 2024-01-11 rancic - optimization for ensemble localization
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! init_mg_parameter -
+! def_maxgen -
+! def_ngens -
+!
+! Functions Included:
+!
+! remarks:
+! ixm(1)=nxm, jym(1)=nym
+! If mod(nxm,2)=0 then mod(im0,2)=0
+! If mod(nxm,2)>0 then mod(im0,8)=0 (for 4 generations)
+! (This will keep the right boundary of all decompmisitions
+! at same physical location)
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use kinds, only: i_kind,r_kind
+use jp_pietc, only: u1
+
+implicit none
+type:: mg_parameter_type
+!-----------------------------------------------------------------------
+!***
+!*** Namelist parameters
+!***
+real(r_kind):: mg_ampl01,mg_ampl02,mg_ampl03
+real(r_kind):: mg_weig1,mg_weig2,mg_weig3,mg_weig4
+integer(i_kind):: mgbf_proc !1-2: 3D filter (1: radial, 2: line)
+ !3-5: 2D filter for static B (3: radial, 4: line, 5: isotropic line)
+ !6-8: 2D filter for localization (6: radial, 7: line, 8: isotropic line)
+logical:: mgbf_line
+integer(i_kind):: nxPE,nyPE,im_filt,jm_filt
+logical:: lquart,lhelm
+
+!***
+!*** Number of generations
+!***
+integer(i_kind):: gm
+integer(i_kind):: gm_max
+
+!***
+!*** Horizontal resolution
+!***
+
+!
+! Original number of data on GSI analysis grid
+!
+integer(i_kind):: nA_max0
+integer(i_kind):: mA_max0
+
+!
+! Global number of data on Analysis grid
+!
+integer(i_kind):: nm0
+integer(i_kind):: mm0
+
+!
+! Number of PEs on Analysis grid
+!
+integer(i_kind):: nxm
+integer(i_kind):: nym
+
+!
+! Number of data on local Analysis grid
+!
+integer(i_kind):: nm
+integer(i_kind):: mm
+
+!
+! Number of data on global Filter grid
+!
+integer(i_kind):: im00
+integer(i_kind):: jm00
+
+!
+! Number of data on local Filter grid
+!
+integer(i_kind):: im
+integer(i_kind):: jm
+
+!
+! Initial index on local Filter grid
+!
+integer(i_kind):: i0
+integer(i_kind):: j0
+!
+! Initial index on local analysis grid
+!
+integer(i_kind):: n0
+integer(i_kind):: m0
+
+!
+! Halo on local Filter grid
+!
+integer(i_kind):: ib
+integer(i_kind):: jb
+
+!
+! Halo on local Analysis grid
+!
+integer(i_kind):: nb
+integer(i_kind):: mb
+
+integer(i_kind):: hx,hy,hz
+integer(i_kind):: p
+integer(i_kind):: nh,nfil
+real(r_kind):: pasp01,pasp02,pasp03
+real(r_kind):: pee2,rmom2_1,rmom2_2,rmom2_3,rmom2_4
+
+integer, allocatable, dimension(:):: maxpe_fgen
+integer, allocatable, dimension(:):: ixm,jym,nxy
+integer, allocatable, dimension(:):: im0,jm0
+integer, allocatable, dimension(:):: Fimax,Fjmax
+integer, allocatable, dimension(:):: FimaxL,FjmaxL
+
+integer(i_kind):: npes_filt
+integer(i_kind):: maxpe_filt
+
+integer(i_kind):: imL,jmL
+integer(i_kind):: imH,jmH
+integer(i_kind):: lm_a ! number of vertical layers in analysis fields
+integer(i_kind):: lm ! number of vertical layers in filter grids
+integer(i_kind):: km2 ! number of 2d variables for filtering
+integer(i_kind):: km3 ! number of 3d variables for filtering
+integer(i_kind):: n_ens ! number of ensemble members
+integer(i_kind):: km_a ! total number of horizontal levels for analysis
+integer(i_kind):: km_all ! total number of k levels of ensemble for filtering
+integer(i_kind):: km_a_all ! total number of k levels of ensemble
+integer(i_kind):: km2_all ! total number of k horizontal levels of ensemble for filtering
+integer(i_kind):: km3_all ! total number of k vertical levels of ensemble
+logical :: l_loc ! logical flag for localization
+logical :: l_filt_g1 ! logical flag for filtering of generation one
+logical :: l_lin_vertical ! logical flag for linear interpolation in vertcial
+logical :: l_lin_horizontal ! logical flag for linear interpolation in horizontal
+logical :: l_quad_horizontal ! logical flag for quadratic interpolation in horizontal
+logical :: l_new_map ! logical flag for new mapping between analysis and filter grid
+logical :: l_vertical_filter ! logical flag for vertical filtering
+integer(i_kind):: km ! number of vertically stacked all variables (km=km2+lm*km3)
+integer(i_kind):: km_4
+integer(i_kind):: km_16
+integer(i_kind):: km_64
+
+real(r_kind):: lengthx,lengthy,xa0,ya0,xf0,yf0
+real(r_kind):: dxf,dyf,dxa,dya
+
+integer(i_kind):: npadx ! x padding on analysis grid
+integer(i_kind):: mpady ! y padding on analysis grid
+
+integer(i_kind):: ipadx ! x padding on filter decomposition
+integer(i_kind):: jpady ! y padding on filter deocmposition
+
+!
+! Just for standalone test
+!
+logical:: ldelta
+
+!from mg_mppstuff.f90
+character(len=5):: c_mype
+integer(i_kind):: mype
+integer(i_kind):: npes,iTYPE,rTYPE,dTYPE,mpi_comm_comp,ierr,ierror
+integer(i_kind):: mpi_comm_work,group_world,group_work
+integer(i_kind):: mype_gr,npes_gr
+integer(i_kind):: my_hgen
+integer(i_kind):: mype_hgen
+logical:: l_hgen
+integer(i_kind):: nx,my
+!from mg_domain.f90
+logical,dimension(2):: Flwest,Fleast,Flnorth,Flsouth
+integer(i_kind),dimension(2):: Fitarg_n,Fitarg_e,Fitarg_s,Fitarg_w
+integer(i_kind),dimension(2):: Fitarg_sw,Fitarg_se,Fitarg_ne,Fitarg_nw
+logical,dimension(2):: Flsendup_sw,Flsendup_se,Flsendup_nw,Flsendup_ne
+integer(i_kind),dimension(2):: Fitarg_up
+integer(i_kind):: itargdn_sw,itargdn_se,itargdn_ne,itargdn_nw
+integer(i_kind):: itarg_wA,itarg_eA,itarg_sA,itarg_nA
+logical:: lwestA,leastA,lsouthA,lnorthA
+integer(i_kind):: ix,jy
+integer(i_kind),dimension(2):: mype_filt
+!from mg_domain_loc.f90
+integer(i_kind):: nsq21,nsq32,nsq43
+logical,dimension(4):: Flsouth_loc,Flnorth_loc,Flwest_loc,Fleast_loc
+integer(i_kind),dimension(4):: Fitarg_s_loc,Fitarg_n_loc,Fitarg_w_loc,Fitarg_e_loc
+integer(i_kind),dimension(4):: Fitargup_loc12
+integer(i_kind),dimension(4):: Fitargup_loc23
+integer(i_kind),dimension(4):: Fitargup_loc34
+integer(i_kind):: itargdn_sw_loc21,itargdn_se_loc21,itargdn_nw_loc21,itargdn_ne_loc21
+integer(i_kind):: itargdn_sw_loc32,itargdn_se_loc32,itargdn_nw_loc32,itargdn_ne_loc32
+integer(i_kind):: itargdn_sw_loc43,itargdn_se_loc43,itargdn_nw_loc43,itargdn_ne_loc43
+logical:: lsendup_sw_loc,lsendup_se_loc,lsendup_nw_loc,lsendup_ne_loc
+
+contains
+ procedure :: init_mg_parameter
+!from mg_mppstuff.f90
+ procedure :: init_mg_MPI
+ procedure :: finishMPI
+ procedure :: barrierMPI
+!from mg_domain.f90
+ procedure :: init_mg_domain
+ procedure :: init_domain
+ procedure :: init_topology_2d
+ procedure :: real_itarg
+!from mg_domain_loc.f90
+ procedure :: init_domain_loc
+ procedure :: sidesend_loc
+ procedure :: targup_loc
+ procedure :: targdn21_loc
+ procedure :: targdn32_loc
+ procedure :: targdn43_loc
+!from jp_pbfil.f90
+ generic :: cholaspect => cholaspect1,cholaspect2,cholaspect3,cholaspect4
+ procedure,nopass :: cholaspect1,cholaspect2,cholaspect3,cholaspect4
+ generic :: getlinesum => getlinesum1,getlinesum2,getlinesum3
+ procedure :: getlinesum1,getlinesum2,getlinesum3
+ generic :: rbeta => rbeta1,rbeta2,rbeta3,rbeta4,vrbeta1,vrbeta2,vrbeta3,vrbeta4
+ procedure:: rbeta1,rbeta2,rbeta3,rbeta4,vrbeta1,vrbeta2,vrbeta3,vrbeta4
+ generic :: rbetaT => rbeta1t,rbeta2t,rbeta3t,rbeta4t,vrbeta1t,vrbeta2t,vrbeta3t,vrbeta4t
+ procedure:: rbeta1t,rbeta2t,rbeta3t,rbeta4t,vrbeta1t,vrbeta2t,vrbeta3t,vrbeta4t
+end type mg_parameter_type
+
+interface
+!from mg_mppstuff.f90
+ module subroutine init_mg_MPI(this)
+ class(mg_parameter_type),target :: this
+ end subroutine
+ module subroutine finishMPI(this)
+ class(mg_parameter_type),target :: this
+ end subroutine
+ module subroutine barrierMPI(this)
+ class(mg_parameter_type),target :: this
+ end subroutine
+!from mg_domain.f90
+ module subroutine init_mg_domain(this)
+ class(mg_parameter_type)::this
+ end subroutine
+ module subroutine init_domain(this)
+ class(mg_parameter_type),target::this
+ end subroutine
+ module subroutine init_topology_2d(this)
+ class(mg_parameter_type),target::this
+ end subroutine
+ module subroutine real_itarg (this,itarg)
+ class(mg_parameter_type),target::this
+ integer(i_kind), intent(inout):: itarg
+ end subroutine
+!from mg_domain_loc.f90
+ module subroutine init_domain_loc(this)
+ class(mg_parameter_type)::this
+ end subroutine
+ module subroutine sidesend_loc(this)
+ class(mg_parameter_type),target::this
+ end subroutine
+ module subroutine targup_loc(this)
+ class(mg_parameter_type),target::this
+ end subroutine
+ module subroutine targdn21_loc(this)
+ class(mg_parameter_type),target::this
+ end subroutine
+ module subroutine targdn32_loc(this)
+ class(mg_parameter_type),target::this
+ end subroutine
+ module subroutine targdn43_loc(this)
+ class(mg_parameter_type),target::this
+ end subroutine
+!from jp_pbfil.f90
+ module subroutine cholaspect1(lx,mx, el)
+ use kinds, only: dp=>r_kind
+ integer, intent(in ):: lx,mx
+ real(dp),dimension(1,1,lx:mx),intent(inout):: el
+ end subroutine
+ module subroutine cholaspect2(lx,mx, ly,my, el)
+ use kinds, only: dp=>r_kind
+ integer, intent(in ):: lx,mx, ly,my
+ real(dp),dimension(2,2,lx:mx,ly:my),intent(inout):: el
+ real(dp),dimension(2,2):: tel
+ end subroutine
+ module subroutine cholaspect3(lx,mx, ly,my, lz,mz, el)
+ use kinds, only: dp=>r_kind
+ integer, intent(in ):: lx,mx, ly,my, lz,mz
+ real(dp),dimension(3,3,lx:mx,ly:my,lz:mz),intent(inout):: el
+ real(dp),dimension(3,3):: tel
+ end subroutine
+ module subroutine cholaspect4(lx,mx, ly,my, lz,mz, lw,mw,el)
+ use kinds, only: dp=>r_kind
+ integer, intent(in ):: lx,mx, ly,my, lz,mz, lw,mw
+ real(dp),dimension(4,4,lx:mx,ly:my,lz:mz,lw:mw),intent(inout):: el
+ real(dp),dimension(4,4):: tel
+ end subroutine
+ module subroutine getlinesum1(this,hx,lx,mx, el, ss)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx
+ real(dp),dimension(1,1,Lx:Mx),intent(in ):: el
+ real(dp),dimension( lx:mx),intent( out):: ss
+ end subroutine
+ module subroutine getlinesum2(this,hx,lx,mx, hy,ly,my, el, ss)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx, hy,ly,my
+ real(dp),dimension(2,2,Lx:Mx,Ly:My),intent(in ):: el
+ real(dp),dimension( lx:mx,ly:my),intent( out):: ss
+ end subroutine
+ module subroutine getlinesum3(this,hx,lx,mx, hy,ly,my, hz,lz,mz, el, ss)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx, hy,ly,my, hz,lz,mz
+ real(dp),dimension(3,3,Lx:Mx,Ly:My,Lz:Mz),intent(in ):: el
+ real(dp),dimension( lx:mx,ly:my,lz:mz),intent( out):: ss
+ end subroutine
+ module subroutine getlinesum4(this,hx,lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw, el, ss)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw
+ real(dp),dimension(4,4,Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: el
+ real(dp),dimension( lx:mx,ly:my,lz:mz,Lw:Mw),intent( out):: ss
+ end subroutine
+ module subroutine rbeta1(this,hx,lx,mx, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx
+ real(dp),dimension(Lx:Mx),intent(in ):: el
+ real(dp),dimension(Lx:Mx),intent(in ):: ss
+ real(dp),dimension(lx-hx:mx+hx),intent(inout):: a
+ end subroutine
+ module subroutine rbeta2(this,hx,lx,mx, hy,ly,my, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx, hy,ly,my
+ real(dp),dimension(2,2,Lx:Mx,Ly:My),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My),intent(in ):: ss
+ real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy),intent(inout):: a
+ end subroutine
+ module subroutine rbeta3(this,hx,lx,mx, hy,ly,my, hz,lz,mz, el,ss,a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx, hy,ly,my, hz,lz,mz
+ real(dp),dimension(3,3,Lx:Mx,Ly:My,Lz:Mz),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz),intent(in ):: ss
+ real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy,lz-hz:mz+hz),intent(inout):: a
+ end subroutine
+ module subroutine rbeta4(this,hx,lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw, el,ss,a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw
+ real(dp),dimension(4,4,Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: ss
+ real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy,lz-hz:mz+hz,lw-hw:mw+hw),intent(inout):: a
+ end subroutine
+ module subroutine rbeta1T(this,hx,lx,mx, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx
+ real(dp),dimension(1,1,Lx:Mx),intent(in ):: el
+ real(dp),dimension( Lx:Mx),intent(in ):: ss
+ real(dp),dimension(lx-hx:mx+hx),intent(inout):: a
+ end subroutine
+ module subroutine rbeta2T(this,hx,lx,mx, hy,ly,my, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx, hy,ly,my
+ real(dp),dimension(2,2,Lx:Mx,Ly:My),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My),intent(in ):: ss
+ real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy),intent(inout):: a
+ end subroutine
+ module subroutine rbeta3T(this,hx,lx,mx, hy,ly,my, hz,lz,mz, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx, hy,ly,my, hz,lz,mz
+ real(dp),dimension(3,3,Lx:Mx,Ly:My,Lz:Mz),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz),intent(in ):: ss
+ real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy,lz-hz:mz+hz),intent(inout):: a
+ end subroutine
+ module subroutine rbeta4T(this,hx,lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: hx,Lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw
+ real(dp),dimension(4,4,Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: ss
+ real(dp),dimension(lx-hx:mx+hx,ly-hy:my+hy,lz-hz:mz+hz,lw-hw:mw+hw),intent(inout):: a
+ end subroutine
+ module subroutine vrbeta1(this,nv,hx,lx,mx, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: nv,hx,Lx,mx
+ real(dp),dimension(1,1,Lx:Mx),intent(in ):: el
+ real(dp),dimension( Lx:Mx),intent(in ):: ss
+ real(dp),dimension(nv,lx-hx:mx+hx),intent(inout):: a
+ end subroutine
+ module subroutine vrbeta2(this,nv,hx,lx,mx, hy,ly,my, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: nv, hx,Lx,mx, hy,ly,my
+ real(dp),dimension(2,2,Lx:Mx,Ly:My),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My),intent(in ):: ss
+ real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy),intent(inout):: a
+ end subroutine
+ module subroutine vrbeta3(this,nv, hx,lx,mx, hy,ly,my, hz,lz,mz, el,ss,a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: nv, hx,Lx,mx, hy,ly,my, hz,lz,mz
+ real(dp),dimension(3,3,Lx:Mx,Ly:My,Lz:Mz),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz),intent(in ):: ss
+ real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy,lz-hz:mz+hz),intent(inout):: a
+ end subroutine
+ module subroutine vrbeta4(this,nv,hx,lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw, el,ss,a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: nv, hx,Lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw
+ real(dp),dimension(4,4,Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: ss
+ real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy,lz-hz:mz+hz,lw-hw:mw+hw),intent(inout):: a
+ end subroutine
+ module subroutine vrbeta1T(this,nv, hx,lx,mx, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: nv,hx,Lx,mx
+ real(dp),dimension(1,1,Lx:Mx),intent(in ):: el
+ real(dp),dimension( Lx:Mx),intent(in ):: ss
+ real(dp),dimension(nv,lx-hx:mx+hx),intent(inout):: a
+ end subroutine
+ module subroutine vrbeta2T(this,nv,hx,lx,mx, hy,ly,my, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: nv, hx,Lx,mx, hy,ly,my
+ real(dp),dimension(2,2,Lx:Mx,Ly:My),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My),intent(in ):: ss
+ real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy),intent(inout):: a
+ end subroutine
+ module subroutine vrbeta3T(this,nv,hx,lx,mx, hy,ly,my, hz,lz,mz, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: nv, hx,Lx,mx, hy,ly,my, hz,lz,mz
+ real(dp),dimension(3,3,Lx:Mx,Ly:My,Lz:Mz),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz),intent(in ):: ss
+ real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy,lz-hz:mz+hz),intent(inout):: a
+ end subroutine
+ module subroutine vrbeta4T(this,nv,hx,lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw, el,ss, a)
+ use kinds, only: dp=>r_kind
+ class(mg_parameter_type)::this
+ integer, intent(in ):: nv, hx,Lx,mx, hy,ly,my, hz,lz,mz, hw,lw,mw
+ real(dp),dimension(4,4,Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: el
+ real(dp),dimension( Lx:Mx,Ly:My,Lz:Mz,Lw:Mw),intent(in ):: ss
+ real(dp),dimension(nv,lx-hx:mx+hx,ly-hy:my+hy,lz-hz:mz+hz,lw-hw:mw+hw),intent(inout):: a
+ end subroutine
+end interface
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+contains
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+subroutine init_mg_parameter(this,inputfilename)
+!**********************************************************************!
+! !
+! Initialize .... !
+! !
+!**********************************************************************!
+implicit none
+class (mg_parameter_type),target:: this
+integer(i_kind):: g
+character(*):: inputfilename
+
+! Namelist parameters as local variable
+real(r_kind):: mg_ampl01,mg_ampl02,mg_ampl03
+real(r_kind):: mg_weig1,mg_weig2,mg_weig3,mg_weig4
+integer(i_kind):: mgbf_proc
+logical:: mgbf_line
+integer(i_kind):: nxPE,nyPE,im_filt,jm_filt
+logical:: lquart,lhelm
+logical:: ldelta
+
+integer(i_kind):: lm_a ! number of vertical layers in analysis fields
+integer(i_kind):: lm ! number of vertical layers in filter grids
+integer(i_kind):: km2 ! number of 2d variables for filtering
+integer(i_kind):: km3 ! number of 3d variables for filtering
+integer(i_kind):: n_ens ! number of ensemble members
+logical :: l_loc ! logical flag for localization
+logical :: l_filt_g1 ! logical flag for filtering of generation one
+logical :: l_lin_vertical ! logical flag for linear interpolation in vertcial
+logical :: l_lin_horizontal ! logical flag for linear interpolation in horizontal
+logical :: l_quad_horizontal ! logical flag for quadratic interpolation in horizontal
+logical :: l_new_map ! logical flag for new mapping between analysis and filter grid
+logical :: l_vertical_filter ! logical flag for vertical filtering
+integer(i_kind):: gm_max
+
+! Global number of data on Analysis grid
+integer(i_kind):: nm0
+integer(i_kind):: mm0
+
+integer(i_kind):: hx,hy,hz
+integer(i_kind):: p
+
+ namelist /parameters_mgbeta/ mg_ampl01,mg_ampl02,mg_ampl03 &
+ ,mg_weig1,mg_weig2,mg_weig3,mg_weig4 &
+ ,hx,hy,hz,p &
+ ,mgbf_line,mgbf_proc &
+ ,lm_a,lm &
+ ,km2,km3 &
+ ,n_ens &
+ ,l_loc &
+ ,l_filt_g1 &
+ ,l_lin_vertical &
+ ,l_lin_horizontal &
+ ,l_quad_horizontal &
+ ,l_new_map &
+ ,l_vertical_filter &
+ ,ldelta,lquart,lhelm &
+ ,gm_max &
+ ,nm0,mm0 &
+ ,nxPE,nyPE,im_filt,jm_filt
+!
+ open(unit=10,file=inputfilename,status='old',action='read')
+ read(10,nml=parameters_mgbeta)
+ close(unit=10)
+!
+!-----------------------------------------------------------------
+!for safety, copy all namelist loc vars to them of this object
+ this%mg_ampl01=mg_ampl01
+ this%mg_ampl02=mg_ampl02
+ this%mg_ampl03=mg_ampl03
+ this%mg_weig1=mg_weig1
+ this%mg_weig2=mg_weig2
+ this%mg_weig3=mg_weig3
+ this%mg_weig4=mg_weig4
+ this%hx=hx
+ this%hy=hy
+ this%hz=hz
+ this%p =p
+ this%mgbf_line=mgbf_line
+ this%mgbf_proc=mgbf_proc
+ this%lm_a=lm_a
+ this%lm=lm
+ this%km2=km2
+ this%km3=km3
+ this%n_ens=n_ens
+ this%l_loc=l_loc
+ this%l_filt_g1=l_filt_g1
+ this%l_lin_vertical=l_lin_vertical
+ this%l_lin_horizontal=l_lin_horizontal
+ this%l_quad_horizontal=l_quad_horizontal
+ this%l_new_map=l_new_map
+ this%l_vertical_filter=l_vertical_filter
+ this%ldelta=ldelta
+ this%lquart=lquart
+ this%lhelm=lhelm
+ this%nm0=nm0
+ this%mm0=mm0
+ this%nxPE=nxPE
+ this%nyPE=nyPE
+ this%im_filt=im_filt
+ this%jm_filt=jm_filt
+
+ this%nxm = nxPE
+ this%nym = nyPE
+
+ this%im = im_filt
+ this%jm = jm_filt
+
+!-----------------------------------------------------------------
+!
+!
+! For 168 PES
+!
+! nxm = 14
+! nym = 12
+!
+! For 256 PES
+!
+! nxm = 16
+! nym = 16
+!
+! For 336 PES
+!
+! nxm = 28
+! nym = 12
+!
+! For 448 PES
+!
+! nxm = 28
+! nym = 16
+!
+! For 512 PES
+!
+! nxm = 32
+! nym = 16
+!
+! For 704 PES
+!
+! nxm = 32
+! nym = 22
+!
+! For 768 PES
+!
+! nxm = 32
+! nym = 24
+!
+! For 924 PES
+!
+! nxm = 28
+! nym = 33
+!
+! For 1056 PES
+!
+! nxm = 32
+! nym = 33
+!
+! For 1408 PES
+!
+! nxm = 32
+! nym = 44
+!
+! For 1848 PES
+!
+! nxm = 56
+! nym = 33
+!
+! For 2464 PES
+!
+! nxm = 56
+! nym = 44
+
+!
+! Define total number of horizontal levels in the case of ensemble
+!
+
+ this%km_a = this%km2+this%lm_a*this%km3
+ this%km = this%km2+this%lm *this%km3
+
+ this%km_a_all = this%km_a * this%n_ens
+ this%km_all = this%km * this%n_ens
+
+ this%km2_all = this%km2 * this%n_ens
+ this%km3_all = this%km3 * this%n_ens
+
+ this%km_4 = this%km/4
+ this%km_16 = this%km/16
+ this%km_64 = this%km/64
+
+!
+! Define maximum number of generations 'gm'
+!
+
+ call def_maxgen(this%nxm,this%nym,this%gm)
+
+! Restrict to gm_max
+
+ if(this%gm>gm_max) then
+ this%gm=gm_max
+ endif
+ if(this%nxm*this%nym<=1) then
+ this%gm=gm_max
+ endif
+
+!***
+!*** Analysis grid
+!***
+
+!
+! Number of grid intervals on GSI grid for the reduced RTMA domain
+! before padding
+!
+ this%nA_max0 = 1792
+ this%mA_max0 = 1056
+
+!
+! Number of grid points on the analysis grid after padding
+!
+
+ this%nm = this%nm0/this%nxm
+ this%mm = this%mm0/this%nym
+
+!***
+!*** Filter grid
+!***
+
+! im = nm
+! jm = mm
+
+!
+! For 168 PES
+!
+! im = 120
+! jm = 80
+!
+! For 256 PES
+!
+! im = 96
+! jm = 64
+!
+! im = 88
+! jm = 56
+!
+! For 336 PES
+!
+! im = 56
+! jm = 80
+!
+! For 448 PES
+!
+! im = 56
+! jm = 64
+!
+! For 512 PES
+!
+! im = 48
+! jm = 64
+!
+! For 704 PES
+!
+! im = 48
+! jm = 40
+!
+! For 768 PES
+!
+! im = 48
+! jm = 40
+!
+! For 924 PES
+!
+! im = 56
+! jm = 24
+!
+! For 1056 PES
+!
+! im = 48
+! jm = 24
+!
+! For 1408 PES
+!
+! im = 48
+! jm = 20
+!
+! For 1848 PES
+!
+! im = 28
+! jm = 24
+!
+! For 2464 PES
+!
+! im = 28
+! jm = 20
+
+ this%im00 = this%nxm*this%im
+ this%jm00 = this%nym*this%jm
+
+ this%n0 = 1
+ this%m0 = 1
+
+ this%i0 = 1
+ this%j0 = 1
+
+!
+! Make sure that nm0 and mm0 and divisibvle with nxm and nym
+!
+ if(this%nm*this%nxm /= this%nm0 ) then
+ write(17,*) 'nm,nxm,nm0=',this%nm,this%nxm,this%nm0
+ stop 'nm0 is not divisible by nxm'
+ endif
+
+ if(this%mm*this%nym /= this%mm0 ) then
+ write(17,*) 'mm,nym,mm0=',this%mm,this%nym,this%mm0
+ stop 'mm0 is not divisible by nym'
+ endif
+
+!
+! Set number of processors at higher generations
+!
+
+ allocate(this%ixm(this%gm))
+ allocate(this%jym(this%gm))
+ allocate(this%nxy(this%gm))
+ allocate(this%maxpe_fgen(0:this%gm))
+ allocate(this%im0(this%gm))
+ allocate(this%jm0(this%gm))
+ allocate(this%Fimax(this%gm))
+ allocate(this%Fjmax(this%gm))
+ allocate(this%FimaxL(this%gm))
+ allocate(this%FjmaxL(this%gm))
+
+ call def_ngens(this%ixm,this%gm,this%nxm)
+ call def_ngens(this%jym,this%gm,this%nym)
+
+ do g=1,this%gm
+ this%nxy(g)=this%ixm(g)*this%jym(g)
+ enddo
+
+ this%maxpe_fgen(0)= 0
+ do g=1,this%gm
+ this%maxpe_fgen(g)=this%maxpe_fgen(g-1)+this%nxy(g)
+ enddo
+
+ this%maxpe_filt=this%maxpe_fgen(this%gm)
+ this%npes_filt=this%maxpe_filt-this%nxy(1)
+
+ this%im0(1)=this%im00
+ do g=2,this%gm
+ this%im0(g)=this%im0(g-1)/2
+ enddo
+
+ this%jm0(1)=this%jm00
+ do g=2,this%gm
+ this%jm0(g)=this%jm0(g-1)/2
+ enddo
+
+ do g=1,this%gm
+ this%Fimax(g)=this%im0(g)-this%im*(this%ixm(g)-1)
+ this%Fjmax(g)=this%jm0(g)-this%jm*(this%jym(g)-1)
+ enddo
+
+ do g=1,this%gm
+ this%FimaxL(g)=this%Fimax(g)/2
+ this%FjmaxL(g)=this%Fjmax(g)/2
+ enddo
+
+!***
+!*** Filter related parameters
+!**
+ this%lengthx = 1.*this%nm ! arbitrary chosen scale of the domain
+ this%lengthy = 1.*this%mm ! arbitrary chosen scale of the domain
+
+ this%ib=6
+ this%jb=6
+
+ this%dxa =this%lengthx/this%nm
+ this%dxf = this%lengthx/this%im
+ this%nb = 2*this%dxf/this%dxa
+
+ this%dya = this%lengthy/this%mm
+ this%dyf = this%lengthy/this%jm
+ this%mb = 2*this%dyf/this%dya
+
+ this%xa0 = this%dxa*0.5
+ this%ya0 = this%dya*0.5
+
+ this%xf0 = this%dxf*0.5
+ this%yf0 = this%dyf*0.5
+
+ this%imL=this%im/2
+ this%jmL=this%jm/2
+
+ this%imH=this%im0(this%gm)
+ this%jmH=this%jm0(this%gm)
+
+ this%pasp01 = mg_ampl01
+ this%pasp02 = mg_ampl02
+ this%pasp03 = mg_ampl03
+
+ this%nh= max(hx,hy,hz)
+ this%nfil = this%nh + 2
+
+ this%pee2=this%p*2
+ this%rmom2_1=u1/sqrt(this%pee2+3)
+ this%rmom2_2=u1/sqrt(this%pee2+4)
+ this%rmom2_3=u1/sqrt(this%pee2+5)
+ this%rmom2_4=u1/sqrt(this%pee2+6)
+
+!----------------------------------------------------------------------
+end subroutine init_mg_parameter
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+subroutine def_maxgen &
+!**********************************************************************
+! !
+! Given number of PEs in x and y direction decides what is the !
+! maximum number of generations that a multigrid scheme can support !
+! !
+! M. Rancic 2020 !
+!**********************************************************************
+(nxm,nym,gm)
+!----------------------------------------------------------------------
+implicit none
+integer, intent(in):: nxm,nym
+integer, intent(out):: gm
+integer:: npx,npy,gx,gy
+
+ npx = nxm; gx=1
+ Do
+ npx = (npx + 1)/2
+ gx = gx + 1
+ if(npx == 1) exit
+ end do
+
+ npy = nym; gy=1
+ Do
+ npy = (npy + 1)/2
+ gy = gy + 1
+ if(npy == 1) exit
+ end do
+
+ gm = Min(gx,gy)
+
+
+!----------------------------------------------------------------------
+endsubroutine def_maxgen
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+subroutine def_ngens &
+!*********************************************************************!
+! !
+! Given number of generations, find number of PEs is s direction !
+! !
+! M. Rancic 2020 !
+!*********************************************************************!
+(nsm,gm,nsm0)
+!----------------------------------------------------------------------
+implicit none
+integer, intent(in):: gm,nsm0
+integer, dimension(gm), intent(out):: nsm
+integer:: g
+!----------------------------------------------------------------------
+
+ nsm(1)=nsm0
+ Do g=2,gm
+ nsm(g) = (nsm(g-1) + 1)/2
+ end do
+
+!----------------------------------------------------------------------
+endsubroutine def_ngens
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+end module mg_parameter
diff --git a/src/mgbf/mg_timers.f90 b/src/mgbf/mg_timers.f90
new file mode 100644
index 0000000000..0905d4d867
--- /dev/null
+++ b/src/mgbf/mg_timers.f90
@@ -0,0 +1,218 @@
+module mg_timers
+!$$$ submodule documentation block
+! . . . .
+! module: mg_timers
+! prgmmr: jovic org: date: 2017
+!
+! abstract: Measure cpu and wallclock timing
+!
+! module history log:
+! 2020 rancic - adjusted
+! 2023-04-19 lei - object-oriented coding
+! 2024-01-11 rancic - optimization for ensemble localization
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! btim -
+! etim -
+! print_mg_timers -
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+ use mpi
+ use kinds, only: r_kind,i_kind
+ implicit none
+
+ private
+
+ public :: btim, etim, print_mg_timers
+
+ type timer
+ logical :: running = .false.
+ real(r_kind) :: start_clock = 0.0
+ real(r_kind) :: start_cpu = 0.0
+ real(r_kind) :: time_clock = 0.0
+ real(r_kind) :: time_cpu = 0.0
+ end type timer
+
+ type(timer),save,public :: total_tim
+ type(timer),save,public :: init_tim
+ type(timer),save,public :: output_tim
+ type(timer),save,public :: dynamics_tim
+ type(timer),save,public :: upsend_tim
+ type(timer),save,public :: upsend1_tim
+ type(timer),save,public :: upsend2_tim
+ type(timer),save,public :: upsend3_tim
+ type(timer),save,public :: an2filt_tim
+ type(timer),save,public :: filt2an_tim
+ type(timer),save,public :: weight_tim
+ type(timer),save,public :: hfiltT_tim
+ type(timer),save,public :: vfiltT_tim
+ type(timer),save,public :: vadv1_tim
+ type(timer),save,public :: hfilt_tim
+ type(timer),save,public :: vfilt_tim
+ type(timer),save,public :: adv2_tim
+ type(timer),save,public :: vtoa_tim
+ type(timer),save,public :: dnsend_tim
+ type(timer),save,public :: dnsend1_tim
+ type(timer),save,public :: dnsend2_tim
+ type(timer),save,public :: dnsend3_tim
+ type(timer),save,public :: update_tim
+ type(timer),save,public :: physics_tim
+ type(timer),save,public :: radiation_tim
+ type(timer),save,public :: convection_tim
+ type(timer),save,public :: turbulence_tim
+ type(timer),save,public :: microphys_tim
+ type(timer),save,public :: pack_tim
+ type(timer),save,public :: arrn_tim
+ type(timer),save,public :: aintp_tim
+ type(timer),save,public :: intp_tim
+ type(timer),save,public :: bocoT_tim
+ type(timer),save,public :: boco_tim
+
+ integer, parameter, public :: print_clock = 1, &
+ print_cpu = 2, &
+ print_clock_pct = 3, &
+ print_cpu_pct = 4
+
+contains
+
+!-----------------------------------------------------------------------
+ subroutine btim(t)
+ implicit none
+ type(timer), intent(inout) :: t
+
+ if (t%running) then
+ write(0,*)'btim: timer is already running'
+ STOP
+ end if
+ t%running = .true.
+
+ t%start_clock = wtime()
+ t%start_cpu = ctime()
+
+ endsubroutine btim
+!-----------------------------------------------------------------------
+ subroutine etim(t)
+ implicit none
+ type(timer), intent(inout) :: t
+ real(r_kind) :: wt, ct
+
+ wt = wtime()
+ ct = ctime()
+
+ if (.not.t%running) then
+ write(0,*)'etim: timer is not running'
+ STOP
+ end if
+ t%running = .false.
+
+ t%time_clock = t%time_clock + (wt - t%start_clock)
+ t%time_cpu = t%time_cpu + (ct - t%start_cpu)
+ t%start_clock = 0.0
+ t%start_cpu = 0.0
+
+ endsubroutine etim
+!-----------------------------------------------------------------------
+ subroutine print_mg_timers(filename, print_type,mype)
+ use mpi
+ implicit none
+ integer(i_kind),intent(in):: mype
+
+ character(len=*), intent(in) :: filename
+ integer, intent(in) :: print_type
+
+ integer :: fh
+ integer :: ierr
+ integer(kind=MPI_OFFSET_KIND) :: disp
+ integer, dimension(MPI_STATUS_SIZE) :: stat
+ character(len=1024) :: buffer, header
+ integer :: bufsize
+
+ call MPI_File_open(MPI_COMM_WORLD, filename, &
+ MPI_MODE_WRONLY + MPI_MODE_CREATE, &
+ MPI_INFO_NULL, fh, ierr)
+
+ buffer = ' '
+ if ( print_type == print_clock ) then
+ write(buffer,"(I6,12(',',F10.4))") mype, &
+ init_tim%time_clock, &
+ upsend_tim%time_clock, &
+ dnsend_tim%time_clock, &
+ weight_tim%time_clock, &
+ hfiltT_tim%time_clock, &
+ hfilt_tim%time_clock, &
+ filt2an_tim%time_clock, &
+ aintp_tim%time_clock, &
+ intp_tim%time_clock, &
+ an2filt_tim%time_clock, &
+ output_tim%time_clock, &
+ total_tim%time_clock
+ else if ( print_type == print_cpu ) then
+ write(buffer,"(I6,14(',',F10.4))") mype, &
+ init_tim%time_cpu, &
+ an2filt_tim%time_cpu, &
+ vfiltT_tim%time_cpu, &
+ upsend_tim%time_cpu, &
+ hfiltT_tim%time_cpu, &
+ bocoT_tim%time_cpu, &
+ weight_tim%time_cpu, &
+ boco_tim%time_cpu, &
+ hfilt_tim%time_cpu, &
+ dnsend_tim%time_cpu, &
+ vfilt_tim%time_cpu, &
+ filt2an_tim%time_cpu, &
+ output_tim%time_cpu, &
+ total_tim%time_cpu
+ end if
+
+ bufsize = LEN(TRIM(buffer)) + 1
+ buffer(bufsize:bufsize) = NEW_LINE(' ')
+
+ write(header,"(A6,14(',',A10))") "mype", &
+ "init", &
+ "an2filt", &
+ "vfiltT", &
+ "upsend", &
+ "hfiltT", &
+ "bocoT" , &
+ "weight", &
+ "boco", &
+ "hfilt", &
+ "dnsend", &
+ "vfilt", &
+ "filt2an", &
+ "output", &
+ "total"
+
+ header(bufsize:bufsize) = NEW_LINE(' ')
+ disp = 0
+ call MPI_File_write_at(fh, disp, header, bufsize, MPI_BYTE, stat, ierr)
+
+ disp = (mype+1)*bufsize
+ call MPI_File_write_at(fh, disp, buffer, bufsize, MPI_BYTE, stat, ierr)
+
+ call MPI_File_close(fh, ierr)
+
+ endsubroutine print_mg_timers
+!-----------------------------------------------------------------------
+ function wtime()
+ use mpi
+ real(r_kind) :: wtime
+ wtime = MPI_Wtime()
+ endfunction wtime
+!-----------------------------------------------------------------------
+ function ctime()
+ real(r_kind) :: ctime
+ call CPU_TIME(ctime)
+ endfunction ctime
+!-----------------------------------------------------------------------
+end module mg_timers
diff --git a/src/mgbf/mg_transfer.f90 b/src/mgbf/mg_transfer.f90
new file mode 100644
index 0000000000..5f929c0243
--- /dev/null
+++ b/src/mgbf/mg_transfer.f90
@@ -0,0 +1,499 @@
+submodule(mg_intstate) mg_transfer
+!$$$ submodule documentation block
+! . . . .
+! module: mg_transfer
+! prgmmr: rancic org: NOAA/EMC date: 2021
+!
+! abstract: Transfer data between analysis and filter grid
+!
+! module history log:
+! 2023-04-19 lei - object-oriented coding
+! 2024-01-11 rancic - optimization for ensemble localization
+! 2024-02-20 yokota - refactoring to apply for GSI
+!
+! Subroutines Included:
+! anal_to_filt_allmap -
+! filt_to_anal_allmap -
+! anal_to_filt_all -
+! filt_to_anal_all -
+! anal_to_filt_all2 -
+! filt_to_anal_all2 -
+! stack_to_composite -
+! composite_to_stack -
+! S2C_ens -
+! C2S_ens -
+! anal_to_filt -
+! filt_to_anal -
+!
+! Functions Included:
+!
+! remarks:
+!
+! attributes:
+! language: f90
+! machine:
+!
+!$$$ end documentation block
+
+use mpi
+use mg_timers
+use kinds, only: r_kind,i_kind
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+contains
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine anal_to_filt_allmap(this,WORKA)
+!***********************************************************************
+! !
+! Transfer data from analysis to first generaton of filter grid !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+real(r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+if(km_a_all==km_all.and.nm==im.and.mm==jm) then
+ VALL=0.
+ VALL(1:km_all,1:im,1:jm)=WORKA
+elseif(l_new_map) then
+ call this%anal_to_filt_all2(WORKA)
+else
+ call this%anal_to_filt_all(WORKA)
+endif
+!----------------------------------------------------------------------
+endsubroutine anal_to_filt_allmap
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filt_to_anal_allmap(this,WORKA)
+!***********************************************************************
+! !
+! Transfer data from filter to analysis grid !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+real(r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+if(km_a_all==km_all.and.nm==im.and.mm==jm) then
+ WORKA=VALL(1:km_all,1:im,1:jm)
+ VALL=0.
+elseif(l_new_map) then
+ call this%filt_to_anal_all2(WORKA)
+else
+ call this%filt_to_anal_all(WORKA)
+endif
+!----------------------------------------------------------------------
+endsubroutine filt_to_anal_allmap
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine anal_to_filt_all(this,WORKA)
+!***********************************************************************
+! !
+! Transfer data from analysis to first generaton of filter grid !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+real(r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+real(r_kind),allocatable,dimension(:,:,:,:):: A3D
+real(r_kind),allocatable,dimension(:,:,:,:):: F3D
+real(r_kind),allocatable,dimension(:,:,:):: WORK
+integer(i_kind):: L
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+allocate(WORK(km_all,1:nm,1:mm))
+allocate(A3D(km3_all,1:nm,1:mm,lm_a))
+allocate(F3D(km3_all,1:nm,1:mm,lm))
+
+ call btim(an2filt_tim)
+ call this%S2C_ens(WORKA,A3D,1,nm,1,mm,lm_a,km_a,km_a_all)
+
+ if(lm_a>lm) then
+ if(l_lin_vertical) then
+ call this%l_vertical_adjoint_spec(km3_all,lm_a,lm,1,nm,1,mm,A3D,F3D)
+ else
+ call this%lwq_vertical_adjoint_spec(km3_all,lm_a,lm,1,nm,1,mm, &
+ cvf1,cvf2,cvf3,cvf4,lref,A3D,F3D)
+ endif
+ else
+
+ do L=1,lm
+ F3D(:,:,:,L)=A3D(:,:,:,L)
+ enddo
+
+ endif
+
+ call this%C2S_ens(F3D,WORK,1,nm,1,mm,lm,km,km_all)
+
+ call this%anal_to_filt(WORK)
+ call etim(an2filt_tim)
+
+deallocate(A3D,F3D,WORK)
+!----------------------------------------------------------------------
+endsubroutine anal_to_filt_all
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filt_to_anal_all(this,WORKA)
+!***********************************************************************
+! !
+! Transfer data from filter to analysis grid !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+real(r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+real(r_kind),allocatable,dimension(:,:,:,:):: A3D
+real(r_kind),allocatable,dimension(:,:,:,:):: F3D
+real(r_kind),allocatable,dimension(:,:,:):: WORK
+integer(i_kind):: L
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+allocate(WORK(km_all,1:nm,1:mm))
+allocate(A3D(km3_all,1:nm,1:mm,lm_a))
+allocate(F3D(km3_all,1:nm,1:mm,lm))
+
+ call btim(filt2an_tim)
+ call this%filt_to_anal(WORK)
+
+ call this%S2C_ens(WORK,F3D,1,nm,1,mm,lm,km,km_all)
+
+ if(lm_a>lm) then
+ if(l_lin_vertical) then
+ call this%l_vertical_direct_spec(km3_all,lm,lm_a,1,nm,1,mm,F3D,A3D)
+ else
+ call this%lwq_vertical_direct_spec(km3_all,lm,lm_a,1,nm,1,mm, &
+ cvf1,cvf2,cvf3,cvf4,lref,F3D,A3D)
+ endif
+ else
+
+ do L=1,lm
+ A3D(:,:,:,L)=F3D(:,:,:,L)
+ enddo
+
+ endif
+
+ call this%C2S_ens(A3D,WORKA,1,nm,1,mm,lm_a,km_a,km_a_all)
+ call etim(filt2an_tim)
+
+deallocate(A3D,F3D,WORK)
+!----------------------------------------------------------------------
+endsubroutine filt_to_anal_all
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine anal_to_filt_all2(this,WORKA)
+!***********************************************************************
+! !
+! Transfer data from analysis to first generaton of filter grid !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+real(r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+real(r_kind),allocatable,dimension(:,:,:):: WORK
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+allocate(WORK(km_all,1:nm,1:mm))
+
+ call btim(an2filt_tim)
+ if(lm_a>lm) then
+ call this%l_vertical_adjoint_spec2(km3*n_ens,lm_a,lm,1,nm,1,mm,WORKA,WORK)
+ else
+ WORK = WORKA
+ endif
+
+ call this%anal_to_filt(WORK)
+ call etim(an2filt_tim)
+
+deallocate(WORK)
+!----------------------------------------------------------------------
+endsubroutine anal_to_filt_all2
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filt_to_anal_all2(this,WORKA)
+!***********************************************************************
+! !
+! Transfer data from filter to analysis grid !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+real(r_kind):: WORKA(this%km_a_all,1:this%nm,1:this%mm)
+real(r_kind),allocatable,dimension(:,:,:):: WORK
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+allocate(WORK(km_all,1:nm,1:mm))
+
+ call btim(filt2an_tim)
+ call this%filt_to_anal(WORK)
+
+ if(lm_a>lm) then
+ call this%l_vertical_direct_spec2(km3*n_ens,lm,lm_a,1,nm,1,mm,WORK,WORKA)
+ else
+ WORKA = WORK
+ endif
+ call etim(filt2an_tim)
+
+deallocate(WORK)
+!----------------------------------------------------------------------
+endsubroutine filt_to_anal_all2
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine stack_to_composite &
+!***********************************************************************
+! !
+! Transfer data from stack to composite variables !
+! !
+!***********************************************************************
+(this,ARR_ALL,A2D,A3D)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+real(r_kind),dimension(this%km ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy), intent(in):: ARR_ALL
+real(r_kind),dimension(this%km3,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy,this%lm),intent(out):: A3D
+real(r_kind),dimension(this%km2,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy) ,intent(out):: A2D
+integer(i_kind):: i,j,k,L
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+ do L=1,lm
+ do j=1-hy,jm+hy
+ do i=1-hx,im+hx
+ do k=1,km3
+ A3D(k,i,j,L)=ARR_ALL( (k-1)*lm+L,i,j )
+ enddo
+ enddo
+ enddo
+ enddo
+
+ do k=1,km2
+ A2D(k,:,:)=ARR_ALL(km3*lm+k,:,:)
+ enddo
+
+!----------------------------------------------------------------------
+endsubroutine stack_to_composite
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine composite_to_stack &
+!***********************************************************************
+! !
+! Transfer data from composite to stack variables !
+! !
+!***********************************************************************
+(this,A2D,A3D,ARR_ALL)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+real(r_kind),dimension(this%km2,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy), intent(in):: A2D
+real(r_kind),dimension(this%km3,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy,this%lm),intent(in):: A3D
+real(r_kind),dimension(this%km ,1-this%hx:this%im+this%hx,1-this%hy:this%jm+this%hy), intent(out):: ARR_ALL
+integer(i_kind):: i,j,k,L
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+ do L=1,lm
+ do j=1-hy,jm+hy
+ do i=1-hx,im+hx
+ do k=1,km3
+ ARR_ALL( (k-1)*lm+L,i,j )=A3D(k,i,j,L)
+ enddo
+ enddo
+ enddo
+ enddo
+
+ do k=1,km2
+ ARR_ALL(km3*lm+k,:,:)=A2D(k,:,:)
+ enddo
+
+!----------------------------------------------------------------------
+endsubroutine composite_to_stack
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine S2C_ens &
+!***********************************************************************
+! !
+! General transfer data from stack to composite variables for ensemble !
+! !
+!***********************************************************************
+(this,ARR_ALL,A3D,imn,imx,jmn,jmx,lmx,kmx,kmx_all)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer, intent(in):: imn,imx,jmn,jmx,lmx,kmx,kmx_all
+real(r_kind),dimension(kmx_all,imn:imx,jmn:jmx) ,intent(in):: ARR_ALL
+real(r_kind),dimension(this%km3_all,imn:imx,jmn:jmx,lmx),intent(out):: A3D
+integer(i_kind):: i,j,k,L
+integer(i_kind):: n,n_inc
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+ do n=1,n_ens
+ n_inc = kmx*(n-1)
+
+ do L=1,lmx
+ do j=jmn,jmx
+ do i=imn,imx
+ do k=1,km3
+ A3D(km3*(n-1)+k,i,j,L)=ARR_ALL(n_inc+(k-1)*lmx+L,i,j)
+ enddo
+ enddo
+ enddo
+ enddo
+
+ enddo
+!----------------------------------------------------------------------
+endsubroutine S2C_ens
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine C2S_ens &
+!***********************************************************************
+! !
+! General transfer data from composite to stack variables for ensemble !
+! !
+!***********************************************************************
+(this,A3D,ARR_ALL,imn,imx,jmn,jmx,lmx,kmx,kmx_all)
+!----------------------------------------------------------------------
+implicit none
+class(mg_intstate_type),target::this
+integer, intent(in):: imn,imx,jmn,jmx,lmx,kmx,kmx_all
+real(r_kind),dimension(this%km3_all,imn:imx,jmn:jmx,lmx),intent(in):: A3D
+real(r_kind),dimension(kmx_all,imn:imx,jmn:jmx) ,intent(out):: ARR_ALL
+integer(i_kind):: i,j,k,L
+integer(i_kind):: n,n_inc
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+ do n=1,n_ens
+ n_inc = kmx*(n-1)
+
+ do L=1,lmx
+ do j=jmn,jmx
+ do i=imn,imx
+ do k=1,km3
+ ARR_ALL(n_inc+(k-1)*lmx+L,i,j )= A3D(km3*(n-1)+k,i,j,L)
+ enddo
+ enddo
+ enddo
+ enddo
+
+ enddo
+!----------------------------------------------------------------------
+endsubroutine C2S_ens
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine anal_to_filt(this,WORK)
+!***********************************************************************
+! !
+! Transfer data from analysis to first generaton of filter grid !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+real(r_kind):: WORK(this%km_all,1:this%nm,1:this%mm)
+integer(i_kind):: ibm,jbm
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+ VALL=0.
+
+ if(l_lin_horizontal) then
+ ibm=1
+ jbm=1
+ call this%lin_adjoint_offset(WORK,VALL(1:km_all,1-ibm:im+ibm,1-jbm:jm+jbm),km_all,ibm,jbm)
+ elseif(l_quad_horizontal) then
+ ibm=2
+ jbm=2
+ call this%quad_adjoint_offset(WORK,VALL(1:km_all,1-ibm:im+ibm,1-jbm:jm+jbm),km_all,ibm,jbm)
+ else
+ ibm=3
+ jbm=3
+ call this%lsqr_adjoint_offset(WORK,VALL(1:km_all,1-ibm:im+ibm,1-jbm:jm+jbm),km_all,ibm,jbm)
+ endif
+
+!***
+!*** Apply adjoint lateral bc on PKF and WKF
+!***
+
+ call this%bocoT_2d(VALL(1:km_all,1-ibm:im+ibm,1-jbm:jm+jbm),km_all,im,jm,ibm,jbm)
+
+!----------------------------------------------------------------------
+endsubroutine anal_to_filt
+
+!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+module subroutine filt_to_anal(this,WORK)
+!***********************************************************************
+! !
+! Transfer data from filter to analysis grid !
+! !
+!***********************************************************************
+implicit none
+class(mg_intstate_type),target::this
+real(r_kind):: WORK(this%km_all,1:this%nm,1:this%mm)
+integer(i_kind):: ibm,jbm
+include "type_parameter_locpointer.inc"
+include "type_intstat_locpointer.inc"
+include "type_parameter_point2this.inc"
+include "type_intstat_point2this.inc"
+!----------------------------------------------------------------------
+
+ if(l_lin_horizontal) then
+ ibm=1
+ jbm=1
+ elseif(l_quad_horizontal) then
+ ibm=2
+ jbm=2
+ else
+ ibm=3
+ jbm=3
+ endif
+
+!***
+!*** Supply boundary conditions for VALL
+!***
+
+ call this%boco_2d(VALL(1:km_all,1-ibm:im+ibm,1-jbm:jm+jbm),km_all,im,jm,ibm,jbm)
+
+ if(l_lin_horizontal) then
+ call this%lin_direct_offset(VALL(1:km_all,1-ibm:im+ibm,1-jbm:jm+jbm),WORK,km_all,ibm,jbm)
+ elseif(l_quad_horizontal) then
+ call this%quad_direct_offset(VALL(1:km_all,1-ibm:im+ibm,1-jbm:jm+jbm),WORK,km_all,ibm,jbm)
+ else
+ call this%lsqr_direct_offset(VALL(1:km_all,1-ibm:im+ibm,1-jbm:jm+jbm),WORK,km_all,ibm,jbm)
+ endif
+
+!----------------------------------------------------------------------
+endsubroutine filt_to_anal
+
+!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+end submodule mg_transfer
diff --git a/src/mgbf/type_intstat_locpointer.inc b/src/mgbf/type_intstat_locpointer.inc
new file mode 100644
index 0000000000..52cdb687e8
--- /dev/null
+++ b/src/mgbf/type_intstat_locpointer.inc
@@ -0,0 +1,44 @@
+real(r_kind), dimension(:,:,:),pointer:: V
+real(r_kind), dimension(:,:,:),pointer:: VALL
+real(r_kind), dimension(:,:,:),pointer:: HALL
+real(r_kind), dimension(:,:,:),pointer:: a_diff_f
+real(r_kind), dimension(:,:,:),pointer:: a_diff_h
+real(r_kind), dimension(:,:,:),pointer:: b_diff_f
+real(r_kind), dimension(:,:,:),pointer:: b_diff_h
+real(r_kind), dimension(:,:),pointer:: p_eps
+real(r_kind), dimension(:,:),pointer:: p_del
+real(r_kind), dimension(:,:),pointer:: p_sig
+real(r_kind), dimension(:,:),pointer:: p_rho
+real(r_kind), dimension(:,:,:),pointer:: paspx
+real(r_kind), dimension(:,:,:),pointer:: paspy
+real(r_kind), dimension(:,:,:),pointer:: pasp1
+real(r_kind), dimension(:,:,:,:),pointer:: pasp2
+real(r_kind), dimension(:,:,:,:,:),pointer:: pasp3
+real(r_kind), dimension(:,:,:),pointer:: vpasp2
+real(r_kind), dimension(:,:,:),pointer:: hss2
+real(r_kind), dimension(:,:,:,:),pointer:: vpasp3
+real(r_kind), dimension(:,:,:,:),pointer:: hss3
+real(r_kind), dimension(:),pointer:: ssx
+real(r_kind), dimension(:),pointer:: ssy
+real(r_kind), dimension(:),pointer:: ss1
+real(r_kind), dimension(:,:),pointer:: ss2
+real(r_kind), dimension(:,:,:),pointer:: ss3
+integer(fpi), dimension(:,:,:),pointer:: dixs
+integer(fpi), dimension(:,:,:),pointer:: diys
+integer(fpi), dimension(:,:,:),pointer:: dizs
+integer(fpi), dimension(:,:,:,:),pointer:: dixs3
+integer(fpi), dimension(:,:,:,:),pointer:: diys3
+integer(fpi), dimension(:,:,:,:),pointer:: dizs3
+integer(fpi), dimension(:,:,:,:),pointer:: qcols
+integer(i_kind),dimension(:),pointer:: iref,jref
+integer(i_kind),dimension(:),pointer:: Lref,Lref_h
+real(r_kind),dimension(:),pointer:: cvf1,cvf2,cvf3,cvf4
+real(r_kind),dimension(:),pointer:: cvh1,cvh2,cvh3,cvh4
+real(r_kind),dimension(:),pointer:: cx0,cx1,cx2,cx3
+real(r_kind),dimension(:),pointer:: cy0,cy1,cy2,cy3
+real(r_kind),dimension(:),pointer:: p_coef,q_coef
+real(r_kind),dimension(:),pointer:: a_coef,b_coef
+real(r_kind),dimension(:,:),pointer:: cf00,cf01,cf02,cf03 &
+ ,cf10,cf11,cf12,cf13 &
+ ,cf20,cf21,cf22,cf23 &
+ ,cf30,cf31,cf32,cf33
diff --git a/src/mgbf/type_intstat_point2this.inc b/src/mgbf/type_intstat_point2this.inc
new file mode 100644
index 0000000000..ab8923f059
--- /dev/null
+++ b/src/mgbf/type_intstat_point2this.inc
@@ -0,0 +1,83 @@
+V=>this%V
+VALL=>this%VALL
+HALL=>this%HALL
+
+a_diff_f=>this%a_diff_f
+a_diff_h=>this%a_diff_h
+b_diff_f=>this%b_diff_f
+b_diff_h=>this%b_diff_h
+
+p_eps=>this%p_eps
+p_del=>this%p_del
+p_sig=>this%p_sig
+p_rho=>this%p_rho
+paspx=>this%paspx
+paspy=>this%paspy
+pasp1=>this%pasp1
+pasp2=>this%pasp2
+pasp3=>this%pasp3
+
+vpasp2=>this%vpasp2
+hss2=>this%hss2
+vpasp3=>this%vpasp3
+hss3=>this%hss3
+
+ssx=>this%ssx
+ssy=>this%ssy
+ss1=>this%ss1
+ss2=>this%ss2
+ss3=>this%ss3
+
+dixs=>this%dixs
+diys=>this%diys
+dizs=>this%dizs
+
+dixs3=>this%dixs3
+diys3=>this%diys3
+dizs3=>this%dizs3
+
+qcols=>this%qcols
+
+iref=>this%iref
+jref=>this%jref
+Lref=>this%Lref
+Lref_h=>this%Lref_h
+cvf1=>this%cvf1
+cvf2=>this%cvf2
+cvf3=>this%cvf3
+cvf4=>this%cvf4
+cvh1=>this%cvh1
+cvh2=>this%cvh2
+cvh3=>this%cvh3
+cvh4=>this%cvh4
+
+cx0=>this%cx0
+cx1=>this%cx1
+cx2=>this%cx2
+cx3=>this%cx3
+cy0=>this%cy0
+cy1=>this%cy1
+cy2=>this%cy2
+cy3=>this%cy3
+
+p_coef=>this%p_coef
+q_coef=>this%q_coef
+a_coef=>this%a_coef
+b_coef=>this%b_coef
+
+cf00=>this%cf00
+cf01=>this%cf01
+cf02=>this%cf02
+cf03=>this%cf03
+cf10=>this%cf10
+cf11=>this%cf11
+cf12=>this%cf12
+cf13=>this%cf13
+cf20=>this%cf20
+cf21=>this%cf21
+cf22=>this%cf22
+cf23=>this%cf23
+cf30=>this%cf30
+cf31=>this%cf31
+cf32=>this%cf32
+cf33=>this%cf33
diff --git a/src/mgbf/type_parameter_locpointer.inc b/src/mgbf/type_parameter_locpointer.inc
new file mode 100644
index 0000000000..7a8f587dd2
--- /dev/null
+++ b/src/mgbf/type_parameter_locpointer.inc
@@ -0,0 +1,105 @@
+real(r_kind),pointer :: mg_ampl01,mg_ampl02,mg_ampl03
+real(r_kind),pointer:: mg_weig1,mg_weig2,mg_weig3,mg_weig4
+integer(i_kind),pointer:: mgbf_proc
+logical,pointer:: mgbf_line
+integer(i_kind),pointer:: nxPE,nyPE,im_filt,jm_filt
+logical,pointer:: lquart,lhelm
+integer(i_kind),pointer:: gm
+integer(i_kind),pointer:: gm_max
+integer(i_kind),pointer:: nA_max0
+integer(i_kind),pointer:: mA_max0
+integer(i_kind),pointer:: nm0
+integer(i_kind),pointer:: mm0
+integer(i_kind),pointer:: nxm
+integer(i_kind),pointer:: nym
+integer(i_kind),pointer:: nm
+integer(i_kind),pointer:: mm
+integer(i_kind),pointer:: im00
+integer(i_kind),pointer:: jm00
+integer(i_kind),pointer:: im
+integer(i_kind),pointer:: jm
+integer(i_kind),pointer:: i0
+integer(i_kind),pointer:: j0
+integer(i_kind),pointer:: n0
+integer(i_kind),pointer:: m0
+integer(i_kind),pointer:: ib
+integer(i_kind),pointer:: jb
+integer(i_kind),pointer:: nb
+integer(i_kind),pointer:: mb
+integer(i_kind),pointer:: hx,hy,hz
+integer(i_kind),pointer:: p
+integer(i_kind),pointer:: nh,nfil
+real(r_kind),pointer:: pasp01,pasp02,pasp03
+real(r_kind),pointer:: pee2,rmom2_1,rmom2_2,rmom2_3,rmom2_4
+integer, pointer, dimension(:):: maxpe_fgen
+integer, pointer, dimension(:):: ixm,jym,nxy
+integer, pointer, dimension(:):: im0,jm0
+integer, pointer, dimension(:):: Fimax,Fjmax
+integer, pointer, dimension(:):: FimaxL,FjmaxL
+integer(i_kind),pointer:: npes_filt
+integer(i_kind),pointer:: maxpe_filt
+integer(i_kind),pointer:: imL,jmL
+integer(i_kind),pointer:: imH,jmH
+integer(i_kind),pointer:: lm_a ! number of vertical layers in analysis fields
+integer(i_kind),pointer:: lm ! number of vertical layers in filter grids
+integer(i_kind),pointer:: km2 ! number of 2d variables for filtering
+integer(i_kind),pointer:: km3 ! number of 3d variables for filtering
+integer(i_kind),pointer:: n_ens ! number of ensemble members
+integer(i_kind),pointer:: km_a ! total number of horizontal levels for analysis
+integer(i_kind),pointer:: km_all ! total number of k levels of ensemble for filtering
+integer(i_kind),pointer:: km_a_all ! total number of k levels of ensemble
+integer(i_kind),pointer:: km2_all ! total number of k horizontal levels of ensemble for filtering
+integer(i_kind),pointer:: km3_all ! total number of k vertical levels of ensemble
+logical,pointer :: l_loc ! logical flag for localization
+logical,pointer :: l_filt_g1 ! logical flag for filtering of generation one
+logical,pointer :: l_lin_vertical ! logical flag for linear interpolation in vertcial
+logical,pointer :: l_lin_horizontal ! logical flag for linear interpolation in horizontal
+logical,pointer :: l_quad_horizontal ! logical flag for quadratic interpolation in horizontal
+logical,pointer :: l_new_map ! logical flag for new mapping between analysis and filter grid
+logical,pointer :: l_vertical_filter ! logical flag for vertical filtering
+integer(i_kind),pointer:: km ! number of vertically stacked all variables (km=km2+lm*km3)
+integer(i_kind),pointer:: km_4
+integer(i_kind),pointer:: km_16
+integer(i_kind),pointer:: km_64
+real(r_kind),pointer:: lengthx,lengthy,xa0,ya0,xf0,yf0
+real(r_kind),pointer:: dxf,dyf,dxa,dya
+integer(i_kind),pointer:: npadx ! x padding on analysis grid
+integer(i_kind),pointer:: mpady ! y padding on analysis grid
+integer(i_kind),pointer:: ipadx ! x padding on filter decomposition
+integer(i_kind),pointer:: jpady ! y padding on filter deocmposition
+logical,pointer:: ldelta
+
+!from mg_mppstuff.f90
+character(len=5),pointer:: c_mype
+integer(i_kind),pointer:: mype
+integer(i_kind),pointer:: npes,iTYPE,rTYPE,dTYPE,mpi_comm_comp,ierror
+integer(i_kind),pointer:: mpi_comm_work,group_world,group_work
+integer(i_kind),pointer:: mype_gr,npes_gr
+integer(i_kind),pointer:: my_hgen
+integer(i_kind),pointer:: mype_hgen
+logical,pointer:: l_hgen
+integer(i_kind),pointer:: nx,my
+
+!from mg_domain.f90
+logical,dimension(:),pointer:: Flwest,Fleast,Flnorth,Flsouth
+integer(i_kind),dimension(:),pointer:: Fitarg_n,Fitarg_e,Fitarg_s,Fitarg_w
+integer(i_kind),dimension(:),pointer:: Fitarg_sw,Fitarg_se,Fitarg_ne,Fitarg_nw
+logical,dimension(:),pointer:: Flsendup_sw,Flsendup_se,Flsendup_nw,Flsendup_ne
+integer(i_kind),dimension(:),pointer:: Fitarg_up
+integer(i_kind),pointer:: itargdn_sw,itargdn_se,itargdn_ne,itargdn_nw
+integer(i_kind),pointer:: itarg_wA,itarg_eA,itarg_sA,itarg_nA
+logical,pointer:: lwestA,leastA,lsouthA,lnorthA
+integer(i_kind),pointer:: ix,jy
+integer(i_kind),dimension(:),pointer:: mype_filt
+
+!from mg_domain_loc.f90
+integer(i_kind),pointer:: nsq21,nsq32,nsq43
+logical,dimension(:),pointer:: Flsouth_loc,Flnorth_loc,Flwest_loc,Fleast_loc
+integer(i_kind),dimension(:),pointer:: Fitarg_s_loc,Fitarg_n_loc,Fitarg_w_loc,Fitarg_e_loc
+integer(i_kind),dimension(:),pointer:: Fitargup_loc12
+integer(i_kind),dimension(:),pointer:: Fitargup_loc23
+integer(i_kind),dimension(:),pointer:: Fitargup_loc34
+integer(i_kind),pointer:: itargdn_sw_loc21,itargdn_se_loc21,itargdn_nw_loc21,itargdn_ne_loc21
+integer(i_kind),pointer:: itargdn_sw_loc32,itargdn_se_loc32,itargdn_nw_loc32,itargdn_ne_loc32
+integer(i_kind),pointer:: itargdn_sw_loc43,itargdn_se_loc43,itargdn_nw_loc43,itargdn_ne_loc43
+logical,pointer:: lsendup_sw_loc,lsendup_se_loc,lsendup_nw_loc,lsendup_ne_loc
diff --git a/src/mgbf/type_parameter_point2this.inc b/src/mgbf/type_parameter_point2this.inc
new file mode 100644
index 0000000000..310f183311
--- /dev/null
+++ b/src/mgbf/type_parameter_point2this.inc
@@ -0,0 +1,189 @@
+mg_ampl01=>this%mg_ampl01
+mg_ampl02=>this%mg_ampl02
+mg_ampl03=>this%mg_ampl03
+mg_weig1=>this%mg_weig1
+mg_weig2=>this%mg_weig2
+mg_weig3=>this%mg_weig3
+mg_weig4=>this%mg_weig4
+mgbf_proc=>this%mgbf_proc
+mgbf_line=>this%mgbf_line
+nxPE=>this%nxPE
+nyPE=>this%nyPE
+im_filt=>this%im_filt
+jm_filt=>this%jm_filt
+lquart=>this%lquart
+lhelm=>this%lhelm
+gm=>this%gm
+gm_max=>this%gm_max
+nA_max0=>this%nA_max0
+mA_max0=>this%mA_max0
+nm0=>this%nm0
+mm0=>this%mm0
+nxm=>this%nxm
+nym=>this%nym
+nm=>this%nm
+mm=>this%mm
+im00=>this%im00
+jm00=>this%jm00
+im=>this%im
+jm=>this%jm
+i0=>this%i0
+j0=>this%j0
+n0=>this%n0
+m0=>this%m0
+ib=>this%ib
+jb=>this%jb
+nb=>this%nb
+mb=>this%mb
+hx=>this%hx
+hy=>this%hy
+hz=>this%hz
+p=>this%p
+nh=>this%nh
+nfil=>this%nfil
+pasp01=>this%pasp01
+pasp02=>this%pasp02
+pasp03=>this%pasp03
+pee2=>this%pee2
+rmom2_1=>this%rmom2_1
+rmom2_2=>this%rmom2_2
+rmom2_3=>this%rmom2_3
+rmom2_4=>this%rmom2_4
+maxpe_fgen=>this%maxpe_fgen
+ixm=>this%ixm
+jym=>this%jym
+nxy=>this%nxy
+im0=>this%im0
+jm0=>this%jm0
+Fimax=>this%Fimax
+Fjmax=>this%Fjmax
+FimaxL=>this%FimaxL
+FjmaxL=>this%FjmaxL
+npes_filt=>this%npes_filt
+maxpe_filt=>this%maxpe_filt
+imL=>this%imL
+jmL=>this%jmL
+imH=>this%imH
+jmH=>this%jmH
+lm_a=>this%lm_a ! number of vertical layers in analysis fields
+lm=>this%lm ! number of vertical layers in filter grids
+km2=>this%km2 ! number of 2d variables for filtering
+km3=>this%km3 ! number of 3d variables for filtering
+n_ens=>this%n_ens ! number of ensemble members
+km_a=>this%km_a ! total number of horizontal levels for analysis
+km_all=>this%km_all ! total number of k levels of ensemble for filtering
+km_a_all=>this%km_a_all ! total number of k levels of ensemble
+km2_all=>this%km2_all ! total number of k horizontal levels of ensemble for filtering
+km3_all=>this%km3_all ! total number of k vertical levels of ensemble
+l_loc=>this%l_loc ! logical flag for localization
+l_filt_g1=>this%l_filt_g1 ! logical flag for filtering of generation one
+l_lin_vertical=>this%l_lin_vertical ! logical flag for linear interpolation in vertcial
+l_lin_horizontal=>this%l_lin_horizontal ! logical flag for linear interpolation in horizontal
+l_quad_horizontal=>this%l_quad_horizontal ! logical flag for quadratic interpolation in horizontal
+l_new_map=>this%l_new_map ! logical flag for new mapping between analysis and filter grid
+l_vertical_filter=>this%l_vertical_filter ! logical flag for vertical filtering
+km=>this%km ! number of vertically stacked all variables (km=km2+lm*km3)
+km_4=>this%km_4
+km_16=>this%km_16
+km_64=>this%km_64
+lengthx=>this%lengthx
+lengthy=>this%lengthy
+xa0=>this%xa0
+ya0=>this%ya0
+xf0=>this%xf0
+yf0=>this%yf0
+dxf=>this%dxf
+dyf=>this%dyf
+dxa=>this%dxa
+dya=>this%dya
+npadx=>this%npadx ! x padding on analysis grid
+mpady=>this%mpady ! y padding on analysis grid
+ipadx=>this%ipadx ! x padding on filter decomposition
+jpady=>this%jpady ! y padding on filter deocmposition
+ldelta=>this%ldelta
+
+!from mg_mppstuff.f90
+c_mype=>this%c_mype
+mype=>this%mype
+npes=>this%npes
+iTYPE=>this%iTYPE
+rTYPE=>this%rTYPE
+dTYPE=>this%dTYPE
+mpi_comm_comp=>this%mpi_comm_comp
+ierror=>this%ierror
+mpi_comm_work=>this%mpi_comm_work
+group_world=>this%group_world
+group_work=>this%group_work
+mype_gr=>this%mype_gr
+npes_gr=>this%npes_gr
+my_hgen=>this%my_hgen
+mype_hgen=>this%mype_hgen
+l_hgen=>this%l_hgen
+nx=>this%nx
+my=>this%my
+
+!from mg_domain.f90
+Flwest=>this%Flwest
+Fleast=>this%Fleast
+Flnorth=>this%Flnorth
+Flsouth=>this%Flsouth
+Fitarg_n=>this%Fitarg_n
+Fitarg_e=>this%Fitarg_e
+Fitarg_s=>this%Fitarg_s
+Fitarg_w=>this%Fitarg_w
+Fitarg_sw=>this%Fitarg_sw
+Fitarg_se=>this%Fitarg_se
+Fitarg_ne=>this%Fitarg_ne
+Fitarg_nw=>this%Fitarg_nw
+Flsendup_sw=>this%Flsendup_sw
+Flsendup_se=>this%Flsendup_se
+Flsendup_nw=>this%Flsendup_nw
+Flsendup_ne=>this%Flsendup_ne
+Fitarg_up=>this%Fitarg_up
+itargdn_sw=>this%itargdn_sw
+itargdn_se=>this%itargdn_se
+itargdn_ne=>this%itargdn_ne
+itargdn_nw=>this%itargdn_nw
+itarg_wA=>this%itarg_wA
+itarg_eA=>this%itarg_eA
+itarg_sA=>this%itarg_sA
+itarg_nA=>this%itarg_nA
+lwestA=>this%lwestA
+leastA=>this%leastA
+lsouthA=>this%lsouthA
+lnorthA=>this%lnorthA
+ix=>this%ix
+jy=>this%jy
+mype_filt=>this%mype_filt
+
+!from mg_domain_loc.f90
+nsq21=>this%nsq21
+nsq32=>this%nsq32
+nsq43=>this%nsq43
+Flsouth_loc=>this%Flsouth_loc
+Flnorth_loc=>this%Flnorth_loc
+Flwest_loc=>this%Flwest_loc
+Fleast_loc=>this%Fleast_loc
+Fitarg_s_loc=>this%Fitarg_s_loc
+Fitarg_n_loc=>this%Fitarg_n_loc
+Fitarg_w_loc=>this%Fitarg_w_loc
+Fitarg_e_loc=>this%Fitarg_e_loc
+Fitargup_loc12=>this%Fitargup_loc12
+Fitargup_loc23=>this%Fitargup_loc23
+Fitargup_loc34=>this%Fitargup_loc34
+itargdn_sw_loc21=>this%itargdn_sw_loc21
+itargdn_se_loc21=>this%itargdn_se_loc21
+itargdn_nw_loc21=>this%itargdn_nw_loc21
+itargdn_ne_loc21=>this%itargdn_ne_loc21
+itargdn_sw_loc32=>this%itargdn_sw_loc32
+itargdn_se_loc32=>this%itargdn_se_loc32
+itargdn_nw_loc32=>this%itargdn_nw_loc32
+itargdn_ne_loc32=>this%itargdn_ne_loc32
+itargdn_sw_loc43=>this%itargdn_sw_loc43
+itargdn_se_loc43=>this%itargdn_se_loc43
+itargdn_nw_loc43=>this%itargdn_nw_loc43
+itargdn_ne_loc43=>this%itargdn_ne_loc43
+lsendup_sw_loc=>this%lsendup_sw_loc
+lsendup_se_loc=>this%lsendup_se_loc
+lsendup_nw_loc=>this%lsendup_nw_loc
+lsendup_ne_loc=>this%lsendup_ne_loc
diff --git a/ush/build.sh b/ush/build.sh
index 71674c4f4c..a133889eac 100755
--- a/ush/build.sh
+++ b/ush/build.sh
@@ -24,13 +24,12 @@ source $DIR_ROOT/ush/detect_machine.sh
set +x
source $DIR_ROOT/ush/module-setup.sh
module use $DIR_ROOT/modulefiles
-module load gsi_$MACHINE_ID
+module load "gsi_${MACHINE_ID}.${COMPILER}"
module list
set -x
# Set CONTROLPATH variable to user develop installation
CONTROLPATH="$DIR_ROOT/../develop/install/bin"
-
# Collect BUILD Options
CMAKE_OPTS+=" -DCMAKE_BUILD_TYPE=$BUILD_TYPE"
diff --git a/ush/build_4nco_global.sh b/ush/build_4nco_global.sh
index 60382ce9b5..45d5eaf7a1 100755
--- a/ush/build_4nco_global.sh
+++ b/ush/build_4nco_global.sh
@@ -18,6 +18,9 @@ export GSI_MODE="GFS"
export ENKF_MODE="GFS"
export REGRESSION_TESTS="NO"
+# Optionally set compiler flags
+##export FFLAGS="-check all,noarg_temp_created"
+
# Prune the directory structure per NCO liking
if [[ "${PRUNE_4NCO:-}" =~ [yYtT] ]]; then
$DIR_ROOT/ush/prune_4nco_global.sh prune
diff --git a/ush/detect_machine.sh b/ush/detect_machine.sh
index ecd1ad536e..0beb937f7e 100755
--- a/ush/detect_machine.sh
+++ b/ush/detect_machine.sh
@@ -1,20 +1,30 @@
#!/bin/bash
+# The authoritative copy of this script lives in the ufs-weather-model at:
+# https://github.com/ufs-community/ufs-weather-model/blob/develop/tests/detect_machine.sh
+# If any local modifications are made or new platform support added,
+# please consider opening an issue and a PR to the ufs-weather-model
+# so that this copy remains in sync with its authoritative source
+#
+# Thank you for your contribution
+
+# If the MACHINE_ID variable is set, skip this script.
+[[ -n ${MACHINE_ID:-} ]] && return
+
+# First detect w/ hostname
case $(hostname -f) in
- adecflow0[12].acorn.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### acorn
- alogin0[12].acorn.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### acorn
+ adecflow0[12].acorn.wcoss2.ncep.noaa.gov) MACHINE_ID=acorn ;; ### acorn
+ alogin0[12].acorn.wcoss2.ncep.noaa.gov) MACHINE_ID=acorn ;; ### acorn
clogin0[1-9].cactus.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### cactus01-9
clogin10.cactus.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### cactus10
dlogin0[1-9].dogwood.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### dogwood01-9
dlogin10.dogwood.wcoss2.ncep.noaa.gov) MACHINE_ID=wcoss2 ;; ### dogwood10
- gaea9) MACHINE_ID=gaea ;; ### gaea9
- gaea1[0-6]) MACHINE_ID=gaea ;; ### gaea10-16
- gaea9.ncrc.gov) MACHINE_ID=gaea ;; ### gaea9
- gaea1[0-6].ncrc.gov) MACHINE_ID=gaea ;; ### gaea10-16
+ gaea5[1-8]) MACHINE_ID=gaea ;; ### gaea51-58
+ gaea5[1-8].ncrc.gov) MACHINE_ID=gaea ;; ### gaea51-58
- hfe0[1-9]) MACHINE_ID=hera ;; ### hera01-9
+ hfe0[1-9]) MACHINE_ID=hera ;; ### hera01-09
hfe1[0-2]) MACHINE_ID=hera ;; ### hera10-12
hecflow01) MACHINE_ID=hera ;; ### heraecflow01
@@ -25,21 +35,58 @@ case $(hostname -f) in
Orion-login-[1-4].HPC.MsState.Edu) MACHINE_ID=orion ;; ### orion1-4
- cheyenne[1-6].cheyenne.ucar.edu) MACHINE_ID=cheyenne ;; ### cheyenne1-6
- cheyenne[1-6].ib0.cheyenne.ucar.edu) MACHINE_ID=cheyenne ;; ### cheyenne1-6
- chadmin[1-6].ib0.cheyenne.ucar.edu) MACHINE_ID=cheyenne ;; ### cheyenne1-6
+ [Hh]ercules-login-[1-4].[Hh][Pp][Cc].[Mm]s[Ss]tate.[Ee]du) MACHINE_ID=hercules ;; ### hercules1-4
login[1-4].stampede2.tacc.utexas.edu) MACHINE_ID=stampede ;; ### stampede1-4
login0[1-2].expanse.sdsc.edu) MACHINE_ID=expanse ;; ### expanse1-2
discover3[1-5].prv.cube) MACHINE_ID=discover ;; ### discover31-35
+ *) MACHINE_ID=UNKNOWN ;; # Unknown platform
esac
+if [[ ${MACHINE_ID} == "UNKNOWN" ]]; then
+ case ${PW_CSP:-} in
+ "aws" | "google" | "azure") MACHINE_ID=noaacloud ;;
+ *) PW_CSP="UNKNOWN"
+ esac
+fi
+
# Overwrite auto-detect with MACHINE if set
MACHINE_ID=${MACHINE:-${MACHINE_ID}}
-# Append compiler (only on machines that have multiple compilers)
-if [ $MACHINE_ID = hera ] || [ $MACHINE_ID = cheyenne ]; then
- MACHINE_ID=${MACHINE_ID}.${COMPILER}
+# If MACHINE_ID is no longer UNKNNOWN, return it
+if [[ "${MACHINE_ID}" != "UNKNOWN" ]]; then
+ return
+fi
+
+# Try searching based on paths since hostname may not match on compute nodes
+if [[ -d /lfs/h3 ]]; then
+ # We are on NOAA Cactus or Dogwood
+ MACHINE_ID=wcoss2
+elif [[ -d /lfs/h1 && ! -d /lfs/h3 ]]; then
+ # We are on NOAA TDS Acorn
+ MACHINE_ID=acorn
+elif [[ -d /mnt/lfs5 ]]; then
+ # We are on NOAA Jet
+ MACHINE_ID=jet
+elif [[ -d /scratch1 ]]; then
+ # We are on NOAA Hera
+ MACHINE_ID=hera
+elif [[ -d /work ]]; then
+ # We are on MSU Orion or Hercules
+ mount=$(findmnt -n -o SOURCE /home)
+ if [[ ${mount} =~ "hercules" ]]; then
+ MACHINE_ID=hercules
+ else
+ MACHINE_ID=orion
+ fi
+elif [[ -d /gpfs && -d /ncrc ]]; then
+ # We are on GAEA.
+ MACHINE_ID=gaea
+elif [[ -d /data/prod ]]; then
+ # We are on SSEC's S4
+ MACHINE_ID=s4
+else
+ echo WARNING: UNKNOWN PLATFORM 1>&2
fi
diff --git a/ush/module-setup.sh b/ush/module-setup.sh
index 469fd4a3c5..299e13aa4e 100755
--- a/ush/module-setup.sh
+++ b/ush/module-setup.sh
@@ -15,10 +15,17 @@ elif [[ $MACHINE_ID = hera* ]] ; then
fi
module purge
+elif [[ $MACHINE_ID = hercules* ]] ; then
+ # We are on Hercules
+ if ( ! eval module help > /dev/null 2>&1 ) ; then
+ source /apps/other/lmod/lmod/init/bash
+ fi
+ module purge
+
elif [[ $MACHINE_ID = orion* ]] ; then
# We are on Orion
if ( ! eval module help > /dev/null 2>&1 ) ; then
- source /apps/lmod/init/bash
+ source /apps/lmod/lmod/init/bash
fi
module purge
@@ -33,13 +40,6 @@ elif [[ $MACHINE_ID = wcoss2 ]]; then
# We are on WCOSS2
module reset
-elif [[ $MACHINE_ID = cheyenne* ]] ; then
- # We are on NCAR Cheyenne
- if ( ! eval module help > /dev/null 2>&1 ) ; then
- source /glade/u/apps/ch/modulefiles/default/localinit/localinit.sh
- fi
- module purge
-
elif [[ $MACHINE_ID = stampede* ]] ; then
# We are on TACC Stampede
if ( ! eval module help > /dev/null 2>&1 ) ; then
@@ -56,33 +56,8 @@ elif [[ $MACHINE_ID = gaea* ]] ; then
# 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
- 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
- if [[ "$__ms_source_etc_profile" == yes ]] ; then
- source /etc/profile
- unset __ms_source_etc_profile
fi
+ module reset
elif [[ $MACHINE_ID = expanse* ]]; then
# We are on SDSC Expanse
@@ -98,6 +73,10 @@ elif [[ $MACHINE_ID = discover* ]]; then
export PATH=$PATH:$SPACK_ROOT/bin
. $SPACK_ROOT/share/spack/setup-env.sh
+elif [[ $MACHINE_ID = noaacloud* ]]; then
+ # We are on NOAA Cloud
+ module purge
+
else
echo WARNING: UNKNOWN PLATFORM 1>&2
fi
diff --git a/ush/prune_4nco_global.sh b/ush/prune_4nco_global.sh
index 0e1eba2ead..149d2bab50 100755
--- a/ush/prune_4nco_global.sh
+++ b/ush/prune_4nco_global.sh
@@ -15,6 +15,8 @@
# removed directories and files
#
+function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
+
set -ex
mode=$1
@@ -23,7 +25,14 @@ mode=$1
if [[ "$mode" = "prune" ]]; then
string="rm -r"
elif [[ "$mode" = "restore" ]]; then
- string="reset HEAD"
+ git_ver=$(git version | cut -d" " -f3)
+ if [ $(version $git_ver) -lt $(version "2.23.0") ]; then
+ use_checkout="YES"
+ string="checkout"
+ else
+ use_checkout="NO"
+ string="restore"
+ fi
else
echo " "
echo "***ERROR*** invalid mode= $mode"
@@ -46,38 +55,58 @@ echo " "
cd $topdir
rlist="regression src/GSD unit-tests"
for type in $rlist; do
- git $string ${type}*
- rc=$?
- if [[ $rc -ne 0 ]]; then
- echo "***ERROR* git $string ${type}"
- exit
- fi
- if [[ "$mode" = "restore" ]]; then
- git checkout ${type}*
- rc=$?
- if [[ $rc -ne 0 ]]; then
- echo "***ERROR* git checkout ${type}"
+ if [[ "$mode" = "prune" ]]; then
+ if [ -e $type ]; then
+ git $string ${type}*
+ rc=$?
+ if [[ $rc -ne 0 ]]; then
+ echo "***ERROR*** git $string ${type}"
+ exit
+ fi
+ fi
+ elif [[ "$mode" = "restore" ]]; then
+ if [[ "$use_checkout" = "YES" ]]; then
+ git reset HEAD ${type}*
+ git checkout ${type}*
+ rc=$?
+ else
+ git restore --staged ${type}*
+ git restore ${type}*
+ rc=$?
+ fi
+ if [[ $rc -ne 0 ]]; then
+ echo "***ERROR*** restore failed for ${type}"
exit
- fi
+ fi
fi
done
# Process doc directories and files
cd $topdir/doc
-rlist="EnKF_user_guide GSI_user_guide README.discover"
+rlist="EnKF_user_guide GSI_user_guide README.discover Release_Notes.fv3gfs_da.v15.0.0.txt Release_Notes.gfsda.v16.0.0.txt"
for type in $rlist; do
- git $string ${type}*
- rc=$?
- if [[ $rc -ne 0 ]]; then
- echo "***ERROR* git $string ${type}"
- exit
- fi
- if [[ "$mode" = "restore" ]]; then
- git checkout ${type}*
- rc=$?
+ if [[ "$mode" = "prune" ]]; then
+ if [ -e $type ]; then
+ git $string ${type}*
+ rc=$?
+ if [[ $rc -ne 0 ]]; then
+ echo "***ERROR*** git $string ${type}"
+ exit
+ fi
+ fi
+ elif [[ "$mode" = "restore" ]]; then
+ if [[ "$use_checkout" = "YES" ]]; then
+ git reset HEAD ${type}*
+ git checkout ${type}*
+ rc=$?
+ else
+ git restore --staged ${type}*
+ git restore ${type}*
+ rc=$?
+ fi
if [[ $rc -ne 0 ]]; then
- echo "***ERROR* git checkout ${type}"
+ echo "***ERROR*** restore failed for ${type}"
exit
fi
fi
@@ -88,17 +117,27 @@ done
cd $topdir/ush
rlist="sub"
for type in $rlist; do
- git $string ${type}*
- rc=$?
- if [[ $rc -ne 0 ]]; then
- echo "***ERROR* git $string ${type}"
- exit
- fi
- if [[ "$mode" = "restore" ]]; then
- git checkout ${type}*
- rc=$?
+ if [[ "$mode" = "prune" ]]; then
+ if [ -e $type ]; then
+ git $string ${type}*
+ rc=$?
+ if [[ $rc -ne 0 ]]; then
+ echo "***ERROR*** git $string ${type}"
+ exit
+ fi
+ fi
+ elif [[ "$mode" = "restore" ]]; then
+ if [[ "$use_checkout" = "YES" ]]; then
+ git reset HEAD ${type}*
+ git checkout ${type}*
+ rc=$?
+ else
+ git restore --staged ${type}*
+ git restore ${type}*
+ rc=$?
+ fi
if [[ $rc -ne 0 ]]; then
- echo "***ERROR* git checkout ${type}"
+ echo "***ERROR*** restore failed for ${type}"
exit
fi
fi
diff --git a/ush/run_observer/README b/ush/run_observer/README
new file mode 100644
index 0000000000..5e68d63929
--- /dev/null
+++ b/ush/run_observer/README
@@ -0,0 +1,5 @@
+Main driver script is submit_gsi_observer.sh
+
+This calls gsi_observer.sh where the GSI observer is run producing GSI diag files in $workdir/diags ($workdir is defined in submit_gsi_observer.sh)
+
+This calls iodaconv.sh which runs the iodacoverters in $GDASApp and outputs to $workdir/ioda
diff --git a/ush/run_observer/gsi_observer.sh b/ush/run_observer/gsi_observer.sh
new file mode 100755
index 0000000000..7ba80320cf
--- /dev/null
+++ b/ush/run_observer/gsi_observer.sh
@@ -0,0 +1,516 @@
+#!/bin/bash
+#SBATCH -J GSIobserver
+#SBATCH -o GSIobserver.o%j
+#SBATCH -A da-cpu
+#SBATCH -q batch
+#SBATCH -p orion
+#SBATCH --nodes=25
+#SBATCH --ntasks-per-node=8
+#SBATCH --exclusive
+#SBATCH -t 30:00
+# run_gsi_observer.sh
+# run GSI observer for a specified
+# analysis cycle and subset of observations
+# cory.r.martin@noaa.gov
+set -x
+ulimit -s unlimited
+
+# source user configuration
+source $1
+# adate, GSIDIR, GSIFIX
+
+## resolution things for GSI
+export JCAP=1534
+export JCAP_B=1534
+export LEVS=127
+export LONA=3072
+export LATA=1536
+export DELTIM=120
+export NLON=3072
+export NLAT=1538
+
+## load modules for GSI
+#set +x
+MACHINE_ID=$MACHINE
+source $GSIDIR/ush/module-setup.sh
+module use $GSIDIR/modulefiles
+module load gsi_$MACHINE_ID.intel
+module list
+#set -x
+set +eu
+
+## load env vars as needed
+export APRUN_GSI='srun --export=ALL'
+
+## variables for executables
+CRMroot=/work2/noaa/da/cmartin/UFO_eval/geovals/
+gsiexec=$GSIDIR/install/bin/gsi.x
+nccat=$CRMroot/GSI-ncdiag/build/ncdiag/ncdiag_cat_serial.x
+NDATE=${NDATE:-`which ndate`}
+ncpc=/bin/cp
+ncpl="ln -fs"
+
+## get analysis/guess date
+PDYa=`echo $adate | cut -c1-8`
+cyca=`echo $adate | cut -c9-10`
+gdate=`$NDATE -06 $adate`
+PDYg=`echo $gdate | cut -c1-8`
+cycg=`echo $gdate | cut -c9-10`
+
+## variables for other useful paths
+fixgsi=$GSIFIX
+ushgsi=$GSIDIR/ush
+crtm_coeffs=./crtm_coeffs/
+datobs=$dumpdir/${dump}.$PDYa/$cyca/atmos
+datobsnr=$dumpdir/${dump}nr.$PDYa/$cyca/atmos
+datobsur=$dumpdir/${dump}ur.$PDYa/$cyca/atmos
+datges=$gesroot/${dump}.$PDYg/$cycg/model_data/atmos/history/
+datbias=$gesroot/${dump}.$PDYg/$cycg/analysis/atmos/
+prefix_obs=${dump}.t${cyca}z
+prefix_ges=${dump}.t${cycg}z
+suffix=tm00.bufr_d
+# gps DO-1 obs
+gpsobs=/work/noaa/da/Cory.R.Martin/noscrub/UFO_eval/GNSSRO_DO1/$PDYa$cyca/${dump}/gpsrobufr
+
+# forcing it to be gfsv16
+SUFFIX=".nc"
+use_gfs_nemsio=".false."
+use_gfs_ncio=".true."
+
+## paths of fix files
+anavinfo=$fixgsi/global_anavinfo.l${LEVS}.txt
+berror=$fixgsi/Big_Endian/global_berror.l${LEVS}y${NLAT}.f77
+locinfo=$fixgsi/global_hybens_info.l${LEVS}.txt
+satinfo=$fixgsi/global_satinfo.txt
+scaninfo=$fixgsi/global_scaninfo.txt
+satangl=$fixgsi/global_satangbias.txt
+pcpinfo=$fixgsi/global_pcpinfo.txt
+ozinfo=$fixgsi/global_ozinfo.txt
+convinfo=/work2/noaa/da/nesposito/GSI_fixdir/global_convinfo.txt
+vqcdat=$fixgsi/vqctp001.dat
+insituinfo=$fixgsi/global_insituinfo.txt
+errtable=$fixgsi/prepobs_errtable.global
+aeroinfo=$fixgsi/global_aeroinfo.txt
+atmsbeaminfo=$fixgsi/atms_beamwidth.txt
+cloudyinfo=$fixgsi/cloudy_radiance_info.txt
+
+emiscoef_IRwater=$CRTM_FIX/Nalli.IRwater.EmisCoeff.bin
+emiscoef_IRice=$CRTM_FIX/NPOESS.IRice.EmisCoeff.bin
+emiscoef_IRland=$CRTM_FIX/NPOESS.IRland.EmisCoeff.bin
+emiscoef_IRsnow=$CRTM_FIX/NPOESS.IRsnow.EmisCoeff.bin
+emiscoef_VISice=$CRTM_FIX/NPOESS.VISice.EmisCoeff.bin
+emiscoef_VISland=$CRTM_FIX/NPOESS.VISland.EmisCoeff.bin
+emiscoef_VISsnow=$CRTM_FIX/NPOESS.VISsnow.EmisCoeff.bin
+emiscoef_VISwater=$CRTM_FIX/NPOESS.VISwater.EmisCoeff.bin
+emiscoef_MWwater=$CRTM_FIX/FASTEM6.MWwater.EmisCoeff.bin
+aercoef=$CRTM_FIX/AerosolCoeff.bin
+cldcoef=$CRTM_FIX/CloudCoeff.bin
+
+## rm, make, and cd to working directory
+cd $workdir
+rm -rf $workdir/gsi
+mkdir -p $workdir/gsi
+cd $workdir/gsi
+
+## copy executable and fix files
+$ncpc $gsiexec ./gsi.x
+
+$ncpc $anavinfo ./anavinfo
+$ncpc $berror ./berror_stats
+$ncpc $locinfo ./hybens_info
+$ncpc $satinfo ./satinfo
+$ncpc $scaninfo ./scaninfo
+$ncpc $pcpinfo ./pcpinfo
+$ncpc $ozinfo ./ozinfo
+$ncpc $convinfo ./convinfo
+$ncpc $vqcdat ./vqctp001.dat
+$ncpc $insituinfo ./insituinfo
+$ncpc $errtable ./errtable
+$ncpc $aeroinfo ./aeroinfo
+$ncpc $atmsbeaminfo ./atms_beamwidth.txt
+$ncpc $cloudyinfo ./cloudy_radiance_info.txt
+
+## copy CRTM coefficient files based on entries in satinfo file
+mkdir -p ${crtm_coeffs}
+for file in `awk '{if($1!~"!"){print $1}}' satinfo | sort | uniq` ;do
+ $ncpc $CRTM_FIX/${file}.SpcCoeff.bin ${crtm_coeffs}
+ $ncpc $CRTM_FIX/${file}.TauCoeff.bin ${crtm_coeffs}
+done
+$ncpc $emiscoef_IRwater ${crtm_coeffs}Nalli.IRwater.EmisCoeff.bin
+$ncpc $emiscoef_IRice ${crtm_coeffs}NPOESS.IRice.EmisCoeff.bin
+$ncpc $emiscoef_IRsnow ${crtm_coeffs}NPOESS.IRsnow.EmisCoeff.bin
+$ncpc $emiscoef_IRland ${crtm_coeffs}NPOESS.IRland.EmisCoeff.bin
+$ncpc $emiscoef_VISice ${crtm_coeffs}NPOESS.VISice.EmisCoeff.bin
+$ncpc $emiscoef_VISland ${crtm_coeffs}NPOESS.VISland.EmisCoeff.bin
+$ncpc $emiscoef_VISsnow ${crtm_coeffs}NPOESS.VISsnow.EmisCoeff.bin
+$ncpc $emiscoef_VISwater ${crtm_coeffs}NPOESS.VISwater.EmisCoeff.bin
+$ncpc $emiscoef_MWwater ${crtm_coeffs}FASTEM6.MWwater.EmisCoeff.bin
+$ncpc $aercoef ${crtm_coeffs}AerosolCoeff.bin
+$ncpc $cldcoef ${crtm_coeffs}CloudCoeff.bin
+
+## copy observations
+if [[ "$rstprod" = "true" ]]; then
+ $ncpl $datobs/${prefix_obs}.prepbufr ./prepbufr
+ $ncpl $datobs/${prefix_obs}.saphir.${suffix} ./saphirbufr
+ $ncpl $datobs/${prefix_obs}.prepbufr.acft_profiles ./prepbufr_profl
+ $ncpl $datobs/${prefix_obs}.nsstbufr ./nsstbufr
+else
+ $ncpl $datobsur/${prefix_obs}.prepbufr ./prepbufr
+ $ncpl $datobsur/${prefix_obs}.saphir.${suffix} ./saphirbufr
+fi
+# use GNSSRO obs with DO-1 included from Kristen if available
+if [[ -f "$gpsobs" ]]; then
+ $ncpl $gpsobs ./gpsrobufr
+else
+ $ncpl $datobs/${prefix_obs}.gpsro.${suffix} ./gpsrobufr
+fi
+$ncpl $datobs/${prefix_obs}.satwnd.${suffix} ./satwndbufr
+$ncpl $datobs/${prefix_obs}.spssmi.${suffix} ./ssmirrbufr
+$ncpl $datobs/${prefix_obs}.sptrmm.${suffix} ./tmirrbufr
+$ncpl $datobs/${prefix_obs}.osbuv8.${suffix} ./sbuvbufr
+$ncpl $datobs/${prefix_obs}.goesfv.${suffix} ./gsnd1bufr
+$ncpl $datobs/${prefix_obs}.1bamua.${suffix} ./amsuabufr
+$ncpl $datobs/${prefix_obs}.1bamub.${suffix} ./amsubbufr
+$ncpl $datobs/${prefix_obs}.1bhrs2.${suffix} ./hirs2bufr
+$ncpl $datobs/${prefix_obs}.1bhrs3.${suffix} ./hirs3bufr
+$ncpl $datobs/${prefix_obs}.1bhrs4.${suffix} ./hirs4bufr
+$ncpl $datobs/${prefix_obs}.1bmhs.${suffix} ./mhsbufr
+$ncpl $datobs/${prefix_obs}.1bmsu.${suffix} ./msubufr
+$ncpl $datobs/${prefix_obs}.airsev.${suffix} ./airsbufr
+$ncpl $datobs/${prefix_obs}.sevcsr.${suffix} ./seviribufr
+$ncpl $datobs/${prefix_obs}.mtiasi.${suffix} ./iasibufr
+$ncpl $datobs/${prefix_obs}.ssmit.${suffix} ./ssmitbufr
+$ncpl $datobs/${prefix_obs}.ssmisu.${suffix} ./ssmisbufr
+$ncpl $datobs/${prefix_obs}.gome.${suffix} ./gomebufr
+$ncpl $datobs/${prefix_obs}.omi.${suffix} ./omibufr
+$ncpl $datobs/${prefix_obs}.mls.${suffix} ./mlsbufr
+$ncpl $datobs/${prefix_obs}.ompsn8.${suffix} ./ompsnpbufr
+$ncpl $datobs/${prefix_obs}.ompst8.${suffix} ./ompstcbufr
+$ncpl $datobs/${prefix_obs}.eshrs3.${suffix} ./hirs3bufrears
+$ncpl $datobs/${prefix_obs}.esamua.${suffix} ./amsuabufrears
+$ncpl $datobs/${prefix_obs}.esamub.${suffix} ./amsubbufrears
+$ncpl $datobs/${prefix_obs}.atms.${suffix} ./atmsbufr
+$ncpl $datobs/${prefix_obs}.cris.${suffix} ./crisbufr
+$ncpl $datobs/${prefix_obs}.crisf4.${suffix} ./crisfsbufr
+$ncpl $datobs/${prefix_obs}.syndata.tcvitals.tm00 ./tcvitl
+$ncpl $datobs/${prefix_obs}.avcsam.${suffix} ./avhambufr
+$ncpl $datobs/${prefix_obs}.avcspm.${suffix} ./avhpmbufr
+$ncpl $datobs/${prefix_obs}.gmi1cr.${suffix} ./gmibufr
+$ncpl $datobs/${prefix_obs}.esiasi.${suffix} ./iasibufrears
+$ncpl $datobs/${prefix_obs}.hrs3db.${suffix} ./hirs3bufr_db
+$ncpl $datobs/${prefix_obs}.amuadb.${suffix} ./amsuabufr_db
+$ncpl $datobs/${prefix_obs}.amubdb.${suffix} ./amsubbufr_db
+$ncpl $datobs/${prefix_obs}.iasidb.${suffix} ./iasibufr_db
+$ncpl $datobs/${prefix_obs}.crisdb.${suffix} ./crisbufr_db
+$ncpl $datobs/${prefix_obs}.atmsdb.${suffix} ./atmsbufr_db
+$ncpl $datobs/${prefix_obs}.escris.${suffix} ./crisbufrears
+$ncpl $datobs/${prefix_obs}.esatms.${suffix} ./atmsbufrears
+$ncpl $datobs/${prefix_obs}.gsrcsr.${suffix} ./abibufr
+$ncpl $datobs/${prefix_obs}.ahicsr.${suffix} ./ahibufr
+
+## copy gsistats
+$ncpl $datges/${prefix_obs}.gsistat ./gsistat
+
+## copy bias correction, atmospheric and surface files
+$ncpl $datbias/${prefix_ges}.abias ./satbias_in
+$ncpl $datbias/${prefix_ges}.abias_pc ./satbias_pc
+$ncpl $datbias/${prefix_ges}.abias_air ./aircftbias_in
+
+nhr_obsbin=$GSI_background_nhr
+if [[ "$GSI_background_nhr" = "1" ]]; then
+ $ncpl $datges/${prefix_ges}.sfcf003$SUFFIX ./sfcf03
+ $ncpl $datges/${prefix_ges}.sfcf004$SUFFIX ./sfcf04
+ $ncpl $datges/${prefix_ges}.sfcf005$SUFFIX ./sfcf05
+ $ncpl $datges/${prefix_ges}.sfcf006$SUFFIX ./sfcf06
+ $ncpl $datges/${prefix_ges}.sfcf007$SUFFIX ./sfcf07
+ $ncpl $datges/${prefix_ges}.sfcf008$SUFFIX ./sfcf08
+ $ncpl $datges/${prefix_ges}.sfcf009$SUFFIX ./sfcf09
+ $ncpl $datges/${prefix_ges}.atmf003$SUFFIX ./sigf03
+ $ncpl $datges/${prefix_ges}.atmf004$SUFFIX ./sigf04
+ $ncpl $datges/${prefix_ges}.atmf005$SUFFIX ./sigf05
+ $ncpl $datges/${prefix_ges}.atmf006$SUFFIX ./sigf06
+ $ncpl $datges/${prefix_ges}.atmf007$SUFFIX ./sigf07
+ $ncpl $datges/${prefix_ges}.atmf008$SUFFIX ./sigf08
+ $ncpl $datges/${prefix_ges}.atmf009$SUFFIX ./sigf09
+elif [[ "$GSI_background_nhr" = "3" ]]; then
+ $ncpl $datges/${prefix_ges}.sfcf003$SUFFIX ./sfcf03
+ $ncpl $datges/${prefix_ges}.atmf003$SUFFIX ./sigf03
+ $ncpl $datges/${prefix_ges}.sfcf006$SUFFIX ./sfcf06
+ $ncpl $datges/${prefix_ges}.atmf006$SUFFIX ./sigf06
+ $ncpl $datges/${prefix_ges}.sfcf009$SUFFIX ./sfcf09
+ $ncpl $datges/${prefix_ges}.atmf009$SUFFIX ./sigf09
+else
+ $ncpl $datges/${prefix_ges}.sfcf006$SUFFIX ./sfcf06
+ $ncpl $datges/${prefix_ges}.atmf006$SUFFIX ./sigf06
+ nhr_obsbin=6
+fi
+
+## create GSI namelist
+cat > gsiparm.anl << EOF
+&SETUP
+ miter=0,
+ niter(1)=1,niter(2)=1,
+ niter_no_qc(1)=50,niter_no_qc(2)=0,
+ write_diag(1)=.true.,write_diag(2)=.false.,
+ qoption=2,
+ gencode=0,deltim=94.,
+ factqmin=0.5,factqmax=0.0002,
+ iguess=-1,
+ tzr_qc=1,
+ oneobtest=.false.,retrieval=.false.,l_foto=.false.,
+ use_pbl=.false.,use_compress=.true.,nsig_ext=56,gpstop=55.,commgpstop=45.,
+ thin4d=.true.,
+ use_gfs_nemsio=${use_gfs_nemsio},use_gfs_ncio=${use_gfs_ncio},sfcnst_comb=.true.,
+ use_readin_anl_sfcmask=.false.,
+ lrun_subdirs=.true.,
+ crtm_coeffs_path='./crtm_coeffs/',
+ newpc4pred=.true.,adp_anglebc=.true.,angord=4,passive_bc=.true.,use_edges=.false.,
+ diag_precon=.true.,step_start=1.e-3,emiss_bc=.true.,nhr_obsbin=${nhr_obsbin:-3},
+ cwoption=3,imp_physics=11,lupp=.true.,cnvw_option=.false., ta2tb=.false.,
+ netcdf_diag=.true.,binary_diag=.false.,
+ lobsdiag_forenkf=.false.,
+ write_fv3_incr=.true.,
+ $SETUP
+/
+&GRIDOPTS
+ JCAP_B=$JCAP_B,JCAP=$JCAP,NLAT=$NLAT,NLON=$NLON,nsig=$LEVS,
+ regional=.false.,nlayers(63)=1,nlayers(64)=1,
+ $GRIDOPTS
+/
+&BKGERR
+ vs=0.7,
+ hzscl=1.7,0.8,0.5,
+ hswgt=0.45,0.3,0.25,
+ bw=0.0,norsp=4,
+ bkgv_flowdep=.true.,bkgv_rewgtfct=1.5,
+ bkgv_write=.false.,
+ cwcoveqqcov=.false.,
+ $BKGVERR
+/
+&ANBKGERR
+ anisotropic=.false.,
+ $ANBKGERR
+/
+&JCOPTS
+ ljcdfi=.false.,alphajc=0.0,ljcpdry=.true.,bamp_jcpdry=5.0e7,
+ $JCOPTS
+/
+&STRONGOPTS
+ tlnmc_option=2,nstrong=1,nvmodes_keep=8,period_max=6.,period_width=1.5,
+ $STRONGOPTS
+/
+&OBSQC
+ dfact=0.75,dfact1=3.0,noiqc=.true.,oberrflg=.false.,c_varqc=0.04,
+ use_poq7=.true.,qc_noirjaco3_pole=.true.,vqc=.false.,nvqc=.true.,
+ aircraft_t_bc=.true.,biaspredt=1.0e5,upd_aircraft=.true.,cleanup_tail=.true.,
+ tcp_width=70.0,tcp_ermax=7.35,
+ $OBSQC
+/
+&OBS_INPUT
+ dmesh(1)=145.0,dmesh(2)=150.0,dmesh(3)=100.0,dmesh(4)=580,time_window_max=3.0,
+ $OBSINPUT
+/
+OBS_INPUT::
+! dfile dtype dplat dsis dval dthin dsfcalc
+ prepbufr ps null ps 0.0 0 0
+ prepbufr t null t 0.0 0 0
+ prepbufr_profl t null t 0.0 0 0
+ prepbufr q null q 0.0 0 0
+ prepbufr_profl q null q 0.0 0 0
+ prepbufr pw null pw 0.0 0 0
+ prepbufr uv null uv 0.0 0 0
+ prepbufr_profl uv null uv 0.0 0 0
+ satwndbufr uv null uv 0.0 0 0
+# prepbufr spd null spd 0.0 0 0
+# prepbufr dw null dw 0.0 0 0
+# radarbufr rw null rw 0.0 0 0
+# nsstbufr sst nsst sst 0.0 0 0
+ gpsrobufr gps_bnd null gps 0.0 0 0
+# ssmirrbufr pcp_ssmi dmsp pcp_ssmi 0.0 -1 0
+# tmirrbufr pcp_tmi trmm pcp_tmi 0.0 -1 0
+# sbuvbufr sbuv2 n16 sbuv8_n16 0.0 0 0
+# sbuvbufr sbuv2 n17 sbuv8_n17 0.0 0 0
+# sbuvbufr sbuv2 n18 sbuv8_n18 0.0 0 0
+# hirs3bufr hirs3 n17 hirs3_n17 0.0 1 0
+# hirs4bufr hirs4 metop-a hirs4_metop-a 0.0 1 0
+# gimgrbufr goes_img g11 imgr_g11 0.0 1 0
+# gimgrbufr goes_img g12 imgr_g12 0.0 1 0
+# airsbufr airs aqua airs_aqua 0.0 1 0
+ amsuabufr amsua n15 amsua_n15 0.0 1 0
+ amsuabufr amsua n18 amsua_n18 0.0 1 0
+ amsuabufr amsua metop-a amsua_metop-a 0.0 1 0
+ airsbufr amsua aqua amsua_aqua 0.0 1 0
+ amsubbufr amsub n17 amsub_n17 0.0 1 0
+ mhsbufr mhs n18 mhs_n18 0.0 1 0
+ mhsbufr mhs metop-a mhs_metop-a 0.0 1 0
+ ssmitbufr ssmi f15 ssmi_f15 0.0 1 0
+# amsrebufr amsre_low aqua amsre_aqua 0.0 1 0
+# amsrebufr amsre_mid aqua amsre_aqua 0.0 1 0
+# amsrebufr amsre_hig aqua amsre_aqua 0.0 1 0
+ ssmisbufr ssmis f16 ssmis_f16 0.0 1 0
+ ssmisbufr ssmis f17 ssmis_f17 0.0 1 0
+ ssmisbufr ssmis f18 ssmis_f18 0.0 1 0
+ gsnd1bufr sndrd1 g12 sndrD1_g12 0.0 1 0
+ gsnd1bufr sndrd2 g12 sndrD2_g12 0.0 1 0
+ gsnd1bufr sndrd3 g12 sndrD3_g12 0.0 1 0
+ gsnd1bufr sndrd4 g12 sndrD4_g12 0.0 1 0
+ gsnd1bufr sndrd1 g11 sndrD1_g11 0.0 1 0
+ gsnd1bufr sndrd2 g11 sndrD2_g11 0.0 1 0
+ gsnd1bufr sndrd3 g11 sndrD3_g11 0.0 1 0
+ gsnd1bufr sndrd4 g11 sndrD4_g11 0.0 1 0
+ gsnd1bufr sndrd1 g13 sndrD1_g13 0.0 1 0
+ gsnd1bufr sndrd2 g13 sndrD2_g13 0.0 1 0
+ gsnd1bufr sndrd3 g13 sndrD3_g13 0.0 1 0
+ gsnd1bufr sndrd4 g13 sndrD4_g13 0.0 1 0
+ iasibufr iasi metop-a iasi_metop-a 0.0 4 0
+ gomebufr gome metop-a gome_metop-a 0.0 2 0
+ omibufr omi aura omi_aura 0.0 2 0
+ sbuvbufr sbuv2 n19 sbuv8_n19 0.0 0 0
+# hirs4bufr hirs4 n19 hirs4_n19 0.0 1 0
+ amsuabufr amsua n19 amsua_n19 0.0 1 0
+ mhsbufr mhs n19 mhs_n19 0.0 1 0
+ tcvitl tcp null tcp 0.0 0 0
+ seviribufr seviri m08 seviri_m08 0.0 1 0
+ seviribufr seviri m09 seviri_m09 0.0 1 0
+ seviribufr seviri m10 seviri_m10 0.0 1 0
+ seviribufr seviri m11 seviri_m11 0.0 1 0
+# hirs4bufr hirs4 metop-b hirs4_metop-b 0.0 1 0
+ amsuabufr amsua metop-b amsua_metop-b 0.0 1 0
+ mhsbufr mhs metop-b mhs_metop-b 0.0 1 0
+ iasibufr iasi metop-b iasi_metop-b 0.0 4 0
+# gomebufr gome metop-b gome_metop-b 0.0 2 0
+ atmsbufr atms npp atms_npp 0.0 1 0
+ atmsbufr atms n20 atms_n20 0.0 1 0
+ atmsbufr atms n21 atms_n21 0.0 1 0
+# crisbufr cris npp cris_npp 0.0 4 0
+# crisfsbufr cris-fsr npp cris-fsr_npp 0.0 4 0
+ crisfsbufr cris-fsr n20 cris-fsr_n20 0.0 4 0
+ crisfsbufr cris-fsr n21 cris-fsr_n21 0.0 4 0
+# gsnd1bufr sndrd1 g14 sndrD1_g14 0.0 1 0
+# gsnd1bufr sndrd2 g14 sndrD2_g14 0.0 1 0
+# gsnd1bufr sndrd3 g14 sndrD3_g14 0.0 1 0
+# gsnd1bufr sndrd4 g14 sndrD4_g14 0.0 1 0
+# gsnd1bufr sndrd1 g15 sndrD1_g15 0.0 1 0
+# gsnd1bufr sndrd2 g15 sndrD2_g15 0.0 1 0
+# gsnd1bufr sndrd3 g15 sndrD3_g15 0.0 1 0
+# gsnd1bufr sndrd4 g15 sndrD4_g15 0.0 1 0
+# oscatbufr uv null uv 0.0 0 0
+# mlsbufr mls30 aura mls30_aura 0.0 0 0
+ avhambufr avhrr metop-a avhrr3_metop-a 0.0 1 0
+ avhpmbufr avhrr n18 avhrr3_n18 0.0 1 0
+ avhambufr avhrr metop-b avhrr3_metop-b 0.0 1 0
+ avhpmbufr avhrr n19 avhrr3_n19 0.0 1 0
+ amsr2bufr amsr2 gcom-w1 amsr2_gcom-w1 0.0 3 0
+ gmibufr gmi gpm gmi_gpm 0.0 3 0
+ saphirbufr saphir meghat saphir_meghat 0.0 3 0
+ ahibufr ahi himawari8 ahi_himawari8 0.0 1 0
+ abibufr abi g16 abi_g16 0.0 1 0
+ abibufr abi g17 abi_g17 0.0 1 0
+ abibufr abi g18 abi_g18 0.0 1 0
+# rapidscatbufr uv null uv 0.0 0 0
+ ompsnpbufr ompsnp npp ompsnp_npp 0.0 0 0
+ ompstcbufr ompstc8 npp ompstc8_npp 0.0 2 0
+ amsuabufr amsua metop-c amsua_metop-c 0.0 1 0
+ mhsbufr mhs metop-c mhs_metop-c 0.0 1 0
+ iasibufr iasi metop-c iasi_metop-c 0.0 4 0
+::
+&SUPEROB_RADAR
+ $SUPERRAD
+/
+&LAG_DATA
+ $LAGDATA
+/
+&HYBRID_ENSEMBLE
+ l_hyb_ens=.false.,
+ generate_ens=.false.,
+ beta_s0=0.125,readin_beta=.false.,
+ s_ens_h=800.,s_ens_v=-0.8,readin_localization=.true.,
+ aniso_a_en=.false.,oz_univ_static=.false.,uv_hyb_ens=.true.,
+ ensemble_path='./ensemble_data/',
+ ens_fast_read=.true.,
+ $HYBRID_ENSEMBLE
+/
+&RAPIDREFRESH_CLDSURF
+ dfi_radar_latent_heat_time_period=30.0,
+ $RAPIDREFRESH_CLDSURF
+/
+&CHEM
+ $CHEM
+/
+&SINGLEOB_TEST
+ maginnov=0.1,magoberr=0.1,oneob_type='t',
+ oblat=45.,oblon=180.,obpres=1000.,obdattim=${adate},
+ obhourset=0.,
+ $SINGLEOB
+/
+&NST
+ nst_gsi=0,
+ nstinfo=4,fac_dtl=1,fac_tsl=1,zsea1=0,zsea2=0,
+ $NSST
+/
+EOF
+cat gsiparm.anl
+
+## run GSI observer
+export OMP_NUM_THREADS=1
+$APRUN_GSI ./gsi.x > gsi.stdout || exit 1
+
+## cat diags
+ntype=3
+numfile[0]=0
+numfile[1]=0
+numfile[2]=0
+numfile[3]=0
+diagtype[0]="conv conv_gps conv_ps conv_q conv_sst conv_t conv_uv"
+diagtype[1]="pcp_ssmi_dmsp pcp_tmi_trmm"
+diagtype[2]="sbuv2_n16 sbuv2_n17 sbuv2_n18 sbuv2_n19 gome_metop-a gome_metop-b omi_aura mls30_aura ompsnp_npp
+ompstc8_npp"
+diagtype[3]="msu_n14 sndr_g08 sndr_g11 sndr_g12 sndr_g13 sndr_g08_prep sndr_g11_prep sndr_g12_prep sndr_g13_prep sndrd1_g11 sndrd2_g11 sndrd3_g11 sndrd4_g11 sndrd1_g12 sndrd2_g12 sndrd3_g12 sndrd4_g12 sndrd1_g13 sndrd2_g13 sndrd3_g13 sndrd4_g13 sndrd1_g14 sndrd2_g14 sndrd3_g14 sndrd4_g14 sndrd1_g15 sndrd2_g15 sndrd3_g15 sndrd4_g15 amsua_n15 amsua_n16 amsua_n17 amsub_n15 amsub_n16 amsub_n17 hsb_aqua airs_aqua amsua_aqua imgr_g08 imgr_g11 imgr_g12 imgr_g14 imgr_g15 ssmi_f13 ssmi_f15 amsua_n18 amsua_metop-a mhs_n18 mhs_metop-a amsre_low_aqua amsre_mid_aqua amsre_hig_aqua ssmis_f16 ssmis_f17 ssmis_f18 ssmis_f19 ssmis_f20 iasi_metop-a amsua_n19 mhs_n19 seviri_m08 seviri_m09 seviri_m10 seviri_m11 cris_npp cris-fsr_npp cris-fsr_n20 atms_npp atms_n20 amsua_metop-b mhs_metop-b iasi_metop-b avhrr_metop-b avhrr_n18 avhrr_n19 avhrr_metop-a amsr2_gcom-w1 gmi_gpm saphir_meghat ahi_himawari8 abi_g16 abi_g17 amsua_metop-c mhs_metop-c iasi_metop-c avhrr_metop-c viirs-m_npp viirs-m_j1 abi_g18 ahi_himawari9 viirs-m_j2 cris-fsr_n21 atms_n21"
+
+prefix=" dir.*/"
+loops="01"
+for loop in $loops; do
+ case $loop in
+ 01) string=ges;;
+ 03) string=anl;;
+ *) string=$loop;;
+ esac
+ echo $(date) START loop $string >&2
+ n=-1
+ while [ $((n+=1)) -le $ntype ] ;do
+ for type in $(echo ${diagtype[n]}); do
+ count=$(ls ${prefix}${type}_${loop}* | wc -l)
+ if [ $count -gt 0 ]; then
+ file=diag_${type}_${string}.${adate}.nc4
+ # note if the GSI utility is not working correctly, use the python version
+ # same syntax is used to call it, just change what $nccat is
+ $nccat -o $file ${prefix}${type}_${loop}.nc4 &
+ sleep 5
+ echo "diag_${type}_${string}.${adate}*" >> ${diaglist[n]}
+ numfile[n]=$(expr ${numfile[n]} + 1)
+ fi
+ done
+ done
+ echo $(date) END loop $string >&2
+done
+wait
+
+cat `echo fort.*` > gsistat.out
+
+mkdir -p $workdir/diags
+mv diag_* $workdir/diags
+
+## cannot let rstprod data become readable by all
+if [[ "$rstprod" = "true" ]]; then
+ chgrp rstprod $workdir/diags/diag_*
+ chmod 640 $workdir/diags/diag_*
+fi
+
+date
+set +x
+module purge
+set -x
+echo "GSI observer script completed"
+cd $workdir
+echo "Submitting IODA converters script"
+sbatch $GSIDIR/ush/run_observer/iodaconv.sh $GDASApp $workdir $adate
diff --git a/ush/run_observer/iodaconv.sh b/ush/run_observer/iodaconv.sh
new file mode 100755
index 0000000000..94a6db9e07
--- /dev/null
+++ b/ush/run_observer/iodaconv.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+#SBATCH -J iodaconv
+#SBATCH -o iodaconv.o%j
+#SBATCH -A da-cpu
+#SBATCH -q batch
+#SBATCH -p orion
+#SBATCH --nodes=1
+#SBATCH --exclusive
+#SBATCH -t 1:30:00
+# run python ioda-iodaconverters
+# on GSI netCDF diag files to generate
+# IODA formatted observations for UFO H(x)
+# cory.r.martin@noaa.gov
+set -x
+
+GDASApp=$1
+workdir=$2
+adate=$3
+
+# source modulefile to get proper python on environment
+module purge
+module use $GDASApp/modulefiles
+module load GDAS/$MACHINE
+module list
+
+# executable paths
+IODA_iodaconv_iodaconvbin=$GDASApp/build/bin/proc_gsi_ncdiag.py
+IODA_iodaconv_iodacombinebin=$GDASApp/build/bin/combine_obsspace.py
+#IODA_iodaconv_iodaconvgnssrobin=$GDASApp/build/bin/gnssro_gsidiag2ioda
+
+# make working directory
+IODA_data_iodaworkdir=$workdir/iodawork
+rm -rf $IODA_data_iodaworkdir
+mkdir -p $IODA_data_iodaworkdir
+cd $IODA_data_iodaworkdir
+
+# make output directory
+IODA_data_iodaoutdir=$workdir/ioda
+rm -rf $IODA_data_iodaoutdir/obs
+mkdir -p $IODA_data_iodaoutdir/obs
+rm -rf $IODA_data_iodaoutdir/geovals
+mkdir -p $IODA_data_iodaoutdir/geovals
+
+#export PYTHONPATH=$GDASApp/build/lib/python3.7/pyioda:$PYTHONPATH
+#export PYTHONPATH=$GDASApp/build/lib/pyiodaconv:$PYTHONPATH
+export PYTHONPATH=$GDASApp/build/lib/python3.7:$PYTHONPATH
+export PYTHONPATH=$GDASApp/build/lib/python3.7/pyiodaconv:$PYTHONPATH
+#export PYTHONPATH=$GDASApp/iodaconv/src:$PYTHONPATH
+#export PYTHONPATH=$PYTHONPATH:$GDASApp/iodaconv/src
+
+#
+# run script to generate IODA obs files
+$IODA_iodaconv_iodaconvbin -o $IODA_data_iodaoutdir/obs -g $IODA_data_iodaoutdir/geovals $workdir/diags
+#
+# concatenate these files together
+python $IODA_iodaconv_iodacombinebin -i $IODA_data_iodaoutdir/obs/sfc_*.nc4 -o $IODA_data_iodaoutdir/obs/sfc_obs_"$adate".nc4 -g $IODA_data_iodaoutdir/geovals
+python $IODA_iodaconv_iodacombinebin -i $IODA_data_iodaoutdir/obs/sfcship_*.nc4 -o $IODA_data_iodaoutdir/obs/sfcship_obs_"$adate".nc4 -g $IODA_data_iodaoutdir/geovals
+python $IODA_iodaconv_iodacombinebin -i $IODA_data_iodaoutdir/obs/aircraft_*.nc4 -o $IODA_data_iodaoutdir/obs/aircraft_obs_"$adate".nc4 -g $IODA_data_iodaoutdir/geovals
+python $IODA_iodaconv_iodacombinebin -i $IODA_data_iodaoutdir/obs/sondes_ps*.nc4 $IODA_data_iodaoutdir/obs/sondes_q*.nc4 $IODA_data_iodaoutdir/obs/sondes_tsen*.nc4 $IODA_data_iodaoutdir/obs/sondes_tv*.nc4 $IODA_data_iodaoutdir/obs/sondes_uv*.nc4 -o $IODA_data_iodaoutdir/obs/sondes_obs_"$adate".nc4 -g $IODA_data_iodaoutdir/geovals
+python $IODA_iodaconv_iodacombinebin -i $IODA_data_iodaoutdir/obs/sondes_ps*.nc4 $IODA_data_iodaoutdir/obs/sondes_q*.nc4 $IODA_data_iodaoutdir/obs/sondes_tv*.nc4 $IODA_data_iodaoutdir/obs/sondes_uv*.nc4 -o $IODA_data_iodaoutdir/obs/sondes_tvirt_obs_"$adate".nc4 -g $IODA_data_iodaoutdir/geovals
+
+# gnssro converter
+#ln -sf $IODA_data_iodaoutdir/obs/gnssro_obs_${adate}.nc4 ./gnssro_obs_${adate}.nc4
+#$IODA_iodaconv_iodaconvgnssrobin $adate $IODA_data_gsiindir/diag_conv_gps_* 1
+
+date
+echo "GSI ncdiag ioda converter script completed"
diff --git a/ush/run_observer/submit_gsi_observer.sh b/ush/run_observer/submit_gsi_observer.sh
new file mode 100755
index 0000000000..2d9dfcecbd
--- /dev/null
+++ b/ush/run_observer/submit_gsi_observer.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# submit_gsi_observer.sh
+# script to define configuration,
+# prepare, and submit GSI observer job
+# cory.r.martin@noaa.gov
+
+set -x
+
+#---- user modified variables
+# valid time
+cycle=2024021900
+# path to your GSI clone
+THISDIR=`pwd`
+GSIDIR=$THISDIR/../..
+# top level working directory
+workdir=/work2/noaa/da/$LOGNAME/ufoeval/GSIobserver/orion/$cycle/
+# GDASApp clone
+#GDASApp=/work2/noaa/da/$LOGNAME/git/GDASApp
+GDASApp=/work2/noaa/da/$LOGNAME/git/orion/GDASApp
+MACHINE=orion
+
+# gfs or gdas
+dump=gdas
+# restricted data inclusion
+rstprod="true"
+# 6 for 3d, 1 or 3 for 4d
+nhr_bkg=6
+
+# should NOT touch below this line
+CRTM_FIX=/work/noaa/da/eliu/ORION/CRTM-fix/crtm_v2.4.1-jedi.1-fix_gdasapp
+# many people cannot clone this without gerrit permissions
+# plus, I have the C768 berror file here
+# so that GSI observer can run at full background res
+GSIFIX=/work2/noaa/da/cmartin/UFO_eval/geovals/GSI/fix
+dumpdir=/work/noaa/rstprod/dump
+gesroot=/work2/noaa/da/acollard/UFO_eval/data/para/output_ufo_eval_feb2024_9Aug
+
+mkdir -p $workdir
+cd $workdir
+cat > $workdir/config.sh << EOF
+export adate=$cycle
+export GSIDIR=$GSIDIR
+export workdir=$workdir
+export GSIFIX=$GSIFIX
+export dump=$dump
+export dumpdir=$dumpdir
+export gesroot=$gesroot
+export CRTM_FIX=$CRTM_FIX
+export rstprod=$rstprod
+export GSI_background_nhr=$nhr_bkg
+export GDASApp=$GDASApp
+export MACHINE=$MACHINE
+export LD_LIBRARY_PATH=/work/noaa/da/eliu/${MACHINE^^}/CRTM/crtm_v2.4.1-jedi.1/build/lib:${LD_LIBRARY_PATH}
+EOF
+
+#sbatch $GSIDIR/ush/run_observer/gsi_observer.sh $workdir/config.sh
+sbatch $GSIDIR/ush/run_observer/gsi_observer.sh $workdir/config.sh
diff --git a/ush/sub_discover b/ush/sub_discover
index 835cd37ace..5d6364be97 100755
--- a/ush/sub_discover
+++ b/ush/sub_discover
@@ -129,8 +129,8 @@ echo "export OMP_NUM_THREADS=$threads" >> $cfile
echo "" >>$cfile
echo ". "$(awk '{ print $1, $2, $3, $4, $5, $6, $7, $8, $9 }' $regdir/regression_var.out) >>$cfile
echo "" >>$cfile
-echo "module use -a $gsisrc/modulefiles" >> $cfile
-echo "module load gsi_discover" >> $cfile
+echo "module use -a $modulefiles" >> $cfile
+echo "module load gsi_discover.intel" >> $cfile
echo "" >>$cfile
echo "jobname=$jobname" >>$cfile
echo "" >>$cfile
diff --git a/ush/sub_gaea b/ush/sub_gaea
new file mode 100755
index 0000000000..9c4e253c93
--- /dev/null
+++ b/ush/sub_gaea
@@ -0,0 +1,170 @@
+#!/bin/sh --login
+set -x
+usage="\
+Usage: $0 [options] executable [args]
+ where the options are:
+ -a account account (default: none)
+ -b binding run smt binding or not (default:NO)
+ -d dirin initial directory (default: cwd)
+ -e envars copy comma-separated environment variables
+ -g group group name
+ -i append standard input to command file
+ -j jobname specify jobname (default: executable basename)
+ -m machine machine on which to run (default: current)
+ -n write command file to stdout rather than submitting it
+ -o output specify output file (default: jobname.out)
+ -p procs[/nodes[/ppreq]
+ number of MPI tasks and optional nodes or Bblocking and
+ ppreq option (N or S) (defaults: serial, Bunlimited, S)
+ -q queue[/qpreq] queue name and optional requirement, e.g. dev/P
+ (defaults: 1 if serial or dev if parallel and none)
+ (queue 3 or 4 is dev or prod with twice tasks over ip)
+ (options: P=parallel, B=bigmem, b=batch)
+ -r rmem[/rcpu] resources memory and cpus/task (default: '1024 mb', 1)
+ -t timew wall time limit in [[hh:]mm:]ss format (default: 900)
+ -u userid userid to run under (default: self)
+ -v verbose mode
+ -w when when to run, in yyyymmddhh[mm], +hh[mm], thh[mm], or
+ Thh[mm] (full, incremental, today or tomorrow) format
+ (default: now)
+Function: This command submits a job to the batch queue."
+subcmd="$*"
+stdin=NO
+nosub=NO
+account=""
+binding="NO"
+dirin=""
+envars=""
+group=""
+jobname=""
+machine=""
+output=""
+procs=0
+nodes=""
+ppreq=""
+queue=""
+qpreq=""
+rmem="1024"
+rcpu="1"
+timew="900"
+userid=""
+verbose=NO
+when=""
+while getopts a:b:d:e:g:ij:m:no:p:q:r:t:u:vw: opt;do
+ case $opt in
+ a) account="$OPTARG";;
+ b) binding="$OPTARG";;
+ d) dirin="$OPTARG";;
+ e) envars="$OPTARG";;
+ g) group="$OPTARG";;
+ i) stdin=YES;;
+ j) jobname=$OPTARG;;
+ m) machine="$OPTARG";;
+ n) nosub=YES;;
+ o) output=$OPTARG;;
+ p) procs=$(echo $OPTARG/|cut -d/ -f1);nodes=$(echo $OPTARG/|cut -d/ -f2);ppreq=$(echo $OPTARG/|cut -d/ -f3);;
+ q) queue=$(echo $OPTARG/|cut -d/ -f1);qpreq=$(echo $OPTARG/|cut -d/ -f2);;
+ r) rmem=$(echo $OPTARG/|cut -d/ -f1);rcpu=$(echo $OPTARG/|cut -d/ -f2);;
+ t) timew=$OPTARG;;
+ u) userid=$OPTARG;;
+ v) verbose=YES;;
+ w) when=$OPTARG;;
+ \?) echo $0: invalid option >&2;echo "$usage" >&2;exit 1;;
+ esac
+done
+shift $(($OPTIND-1))
+if [[ $# -eq 0 ]];then
+ echo $0: missing executable name >&2;echo "$usage" >&2;exit 1
+fi
+exec=$1
+if [[ ! -s $exec ]]&&which $exec >/dev/null 2>&1;then
+ exec=$(which $exec)
+fi
+shift
+args="$*"
+bn=$(basename $exec)
+export jobname=${jobname:-$bn}
+output=${output:-$jobname.out}
+myuser=$LOGNAME
+myhost=$(hostname)
+
+if [ -d /gpfs/f5/epic/scratch/${USER}/$LOGNAME ]; then
+ DATA=/gpfs/f5/epic/scratch/${USER}/$LOGNAME/tmp
+fi
+DATA=${DATA:-$ptmp/tmp}
+
+mkdir -p $DATA
+
+queue=${queue:-batch}
+timew=${timew:-01:20:00}
+task_node=${task_node:-$procs}
+size=$((nodes*task_node))
+envars=$envars
+threads=${rcpu:-1}
+
+export TZ=GMT
+cfile=$DATA/sub$$
+> $cfile
+echo "#!/bin/bash -l" >> $cfile
+echo "" >> $cfile
+echo "#SBATCH --output=$output" >> $cfile
+echo "#SBATCH --job-name=$jobname" >> $cfile
+echo "#SBATCH --qos=$queue" >> $cfile
+echo "#SBATCH --clusters=c5" >> $cfile
+echo "#SBATCH --time=$timew" >> $cfile
+echo "#SBATCH --nodes=$nodes --ntasks-per-node=$procs --cpus-per-task=$threads" >> $cfile
+echo "#SBATCH --account=$accnt" >> $cfile
+echo "#SBATCH --mem=0" >> $cfile
+
+echo "" >>$cfile
+echo "export ntasks=$(( $nodes * $procs ))" >> $cfile
+echo "export ppn=$procs" >> $cfile
+echo "export threads=$threads" >> $cfile
+echo "export OMP_NUM_THREADS=$threads" >> $cfile
+echo "ulimit -s unlimited" >> $cfile
+
+echo "" >>$cfile
+echo ". "$(awk '{ print $1, $2, $3, $4, $5, $6, $7, $8, $9 }' $regdir/regression_var.out) >>$cfile
+echo "" >>$cfile
+
+echo "module reset" >> $cfile
+echo "module use $modulefiles" >> $cfile
+echo "module load gsi_gaea.intel" >> $cfile
+echo "module list" >> $cfile
+echo "" >>$cfile
+
+cat $exec >> $cfile
+
+if [[ $nosub = YES ]];then
+ cat $cfile
+ exit
+elif [[ $verbose = YES ]];then
+ set -x
+ cat $cfile
+fi
+
+if [[ $stdin = YES ]];then
+ cat
+fi >>$cfile
+if [[ $nosub = YES ]];then
+ cat $cfile
+ exit
+elif [[ $verbose = YES ]];then
+ set -x
+ cat $cfile
+fi
+sbatch=${sbatch:-sbatch}
+
+ofile=$DATA/subout$$
+>$ofile
+chmod 777 $ofile
+$sbatch $cfile >$ofile
+rc=$?
+cat $ofile
+if [[ -w $SUBLOG ]];then
+ jobn=$(grep -i submitted $ofile|head -n1|cut -d\" -f2)
+ date -u +"%Y%m%d%H%M%S : $subcmd : $jobn" >>$SUBLOG
+fi
+rm $cfile $ofile
+[[ $MKDATA = YES ]] && rmdir $DATA
+exit $rc
diff --git a/ush/sub_hera b/ush/sub_hera
index d904417190..c94b734596 100755
--- a/ush/sub_hera
+++ b/ush/sub_hera
@@ -120,10 +120,10 @@ echo "#SBATCH --output=$output"
echo "#SBATCH --job-name=$jobname" >> $cfile
echo "#SBATCH --qos=$queue" >> $cfile
echo "#SBATCH --time=$timew" >> $cfile
-echo "#SBATCH --nodes=$nodes --ntasks-per-node=$procs --cpus-per-task=$threads" >> $cfile
+echo "#SBATCH --nodes=$nodes --ntasks-per-node=$procs --exclusive" >> $cfile
#echo "#SBATCH -j oe" >> $cfile
echo "#SBATCH --account=$accnt" >> $cfile
-echo "#SBATCH --mem=0" >> $cfile
+#cltorg echo "#SBATCH --mem=0" >> $cfile
#echo "#SBATCH -V" >> $cfile
#echo "#PBS -d" >> $cfile
#. $exec >> $cfile
@@ -137,13 +137,12 @@ echo "" >>$cfile
echo ". /apps/lmod/lmod/init/sh" >> $cfile
echo "module purge" >> $cfile
-echo "module use $gsisrc/modulefiles" >> $cfile
+echo "module use $modulefiles" >> $cfile
echo "module load gsi_hera.intel" >> $cfile
echo "module list" >> $cfile
echo "" >>$cfile
cat $exec >> $cfile
-
if [[ $nosub = YES ]];then
cat $cfile
exit
diff --git a/ush/sub_hercules b/ush/sub_hercules
new file mode 100755
index 0000000000..78a0f5daee
--- /dev/null
+++ b/ush/sub_hercules
@@ -0,0 +1,170 @@
+#!/bin/sh --login
+set -x
+usage="\
+Usage: $0 [options] executable [args]
+ where the options are:
+ -a account account (default: none)
+ -b binding run smt binding or not (default:NO)
+ -d dirin initial directory (default: cwd)
+ -e envars copy comma-separated environment variables
+ -g group group name
+ -i append standard input to command file
+ -j jobname specify jobname (default: executable basename)
+ -m machine machine on which to run (default: current)
+ -n write command file to stdout rather than submitting it
+ -o output specify output file (default: jobname.out)
+ -p procs[/nodes[/ppreq]
+ number of MPI tasks and optional nodes or Bblocking and
+ ppreq option (N or S) (defaults: serial, Bunlimited, S)
+ -q queue[/qpreq] queue name and optional requirement, e.g. dev/P
+ (defaults: 1 if serial or dev if parallel and none)
+ (queue 3 or 4 is dev or prod with twice tasks over ip)
+ (options: P=parallel, B=bigmem, b=batch)
+ -r rmem[/rcpu] resources memory and cpus/task (default: '1024 mb', 1)
+ -t timew wall time limit in [[hh:]mm:]ss format (default: 900)
+ -u userid userid to run under (default: self)
+ -v verbose mode
+ -w when when to run, in yyyymmddhh[mm], +hh[mm], thh[mm], or
+ Thh[mm] (full, incremental, today or tomorrow) format
+ (default: now)
+Function: This command submits a job to the batch queue."
+subcmd="$*"
+stdin=NO
+nosub=NO
+account=""
+binding="NO"
+dirin=""
+envars=""
+group=""
+jobname=""
+machine=""
+output=""
+procs=0
+nodes=""
+ppreq=""
+queue=""
+qpreq=""
+rmem="1024"
+rcpu="1"
+timew="900"
+userid=""
+verbose=NO
+when=""
+while getopts a:b:d:e:g:ij:m:no:p:q:r:t:u:vw: opt;do
+ case $opt in
+ a) account="$OPTARG";;
+ b) binding="$OPTARG";;
+ d) dirin="$OPTARG";;
+ e) envars="$OPTARG";;
+ g) group="$OPTARG";;
+ i) stdin=YES;;
+ j) jobname=$OPTARG;;
+ m) machine="$OPTARG";;
+ n) nosub=YES;;
+ o) output=$OPTARG;;
+ p) procs=$(echo $OPTARG/|cut -d/ -f1);nodes=$(echo $OPTARG/|cut -d/ -f2);ppreq=$(echo $OPTARG/|cut -d/ -f3);;
+ q) queue=$(echo $OPTARG/|cut -d/ -f1);qpreq=$(echo $OPTARG/|cut -d/ -f2);;
+ r) rmem=$(echo $OPTARG/|cut -d/ -f1);rcpu=$(echo $OPTARG/|cut -d/ -f2);;
+ t) timew=$OPTARG;;
+ u) userid=$OPTARG;;
+ v) verbose=YES;;
+ w) when=$OPTARG;;
+ \?) echo $0: invalid option >&2;echo "$usage" >&2;exit 1;;
+ esac
+done
+shift $(($OPTIND-1))
+if [[ $# -eq 0 ]];then
+ echo $0: missing executable name >&2;echo "$usage" >&2;exit 1
+fi
+exec=$1
+if [[ ! -s $exec ]]&&which $exec >/dev/null 2>&1;then
+ exec=$(which $exec)
+fi
+shift
+args="$*"
+bn=$(basename $exec)
+export jobname=${jobname:-$bn}
+output=${output:-$jobname.out}
+myuser=$LOGNAME
+myhost=$(hostname)
+exp=${jobname}
+
+DATA=${ptmp:-/work/noaa/da/stmp/$LOGNAME/tmp}
+mkdir -p $DATA
+
+#partition=${partition:-c1ms}
+queue=${queue:-batch}
+timew=${timew:-01:20:00}
+task_node=${task_node:-$procs}
+size=$((nodes*task_node))
+envars=$envars
+threads=${rcpu:-1}
+
+export TZ=GMT
+cfile=$DATA/sub$$
+> $cfile
+#echo "#PBS -S /bin/sh" >> $cfile
+echo "#!/bin/sh --login" >> $cfile
+echo "" >> $cfile
+echo "#SBATCH --output=$output" >> $cfile
+echo "#SBATCH --job-name=$jobname" >> $cfile
+echo "#SBATCH --qos=$queue" >> $cfile
+echo "#SBATCH --partition=$partition" >> $cfile
+echo "#SBATCH --time=$timew" >> $cfile
+echo "#SBATCH --nodes=$nodes --ntasks-per-node=$procs --exclusive" >> $cfile
+echo "#SBATCH --account=$accnt" >> $cfile
+
+echo "" >>$cfile
+echo "export ntasks=$(( $nodes * $procs ))" >> $cfile
+echo "export ppn=$procs" >> $cfile
+echo "export threads=$threads" >> $cfile
+echo "export OMP_NUM_THREADS=$threads" >> $cfile
+echo "ulimit -s unlimited" >> $cfile
+
+echo "" >>$cfile
+echo ". "$(awk '{ print $1, $2, $3, $4, $5, $6, $7, $8, $9 }' $regdir/regression_var.out) >>$cfile
+echo "" >>$cfile
+
+echo ". /apps/other/lmod/lmod/init/sh" >> $cfile
+echo "module purge" >> $cfile
+echo "module use $modulefiles" >> $cfile
+echo "module load gsi_hercules.intel" >> $cfile
+#TODO reenable I_MPI_EXTRA_FILESYSTEM once regional ctests can properly handle parallel I/O on Hercules
+echo "unset I_MPI_EXTRA_FILESYSTEM" >> $cfile
+
+cat $exec >> $cfile
+
+if [[ $nosub = YES ]];then
+ cat $cfile
+ exit
+elif [[ $verbose = YES ]];then
+ set -x
+ cat $cfile
+fi
+
+
+if [[ $stdin = YES ]];then
+ cat
+fi >>$cfile
+if [[ $nosub = YES ]];then
+ cat $cfile
+ exit
+elif [[ $verbose = YES ]];then
+ set -x
+ cat $cfile
+fi
+sbatch=${sbatch:-sbatch}
+
+ofile=$DATA/subout$$
+>$ofile
+chmod 777 $ofile
+$sbatch --export=ALL $cfile >$ofile
+rc=$?
+cat $ofile
+if [[ -w $SUBLOG ]];then
+ jobn=$(grep -i submitted $ofile|head -n1|cut -d\" -f2)
+ date -u +"%Y%m%d%H%M%S : $subcmd : $jobn" >>$SUBLOG
+fi
+rm $cfile $ofile
+[[ $MKDATA = YES ]] && rmdir $DATA
+exit $rc
diff --git a/ush/sub_jet b/ush/sub_jet
index 5bd9a6d68c..96f3eae9b2 100755
--- a/ush/sub_jet
+++ b/ush/sub_jet
@@ -88,7 +88,7 @@ output=${output:-$jobname.out}
myuser=$LOGNAME
myhost=$(hostname)
-DATA=$regdir/regtests/data
+DATA=${DATA:-$ptmp/tmp}
mkdir -p $DATA
@@ -98,41 +98,36 @@ task_node=${task_node:-$procs}
size=$((nodes*task_node))
envars=$envars
threads=${rcpu:-1}
-#envars=$envars,mpi_tasks=$procs
-#Options
-###PBS -l partition=c1ms,size=0528,walltime=01:20:00
-##PBS -l partition=$queue,size=$size,walltime=$timew
-##PBS -S /bin/sh
export TZ=GMT
cfile=$DATA/sub$$
> $cfile
-#echo "#PBS -S /bin/sh" >> $cfile
echo "#!/bin/sh --login" >> $cfile
echo "" >> $cfile
echo "#SBATCH --output=$output" >> $cfile
echo "#SBATCH --job-name=$jobname" >> $cfile
echo "#SBATCH --qos=$queue" >> $cfile
echo "#SBATCH --time=$timew" >> $cfile
-echo "#SBATCH --nodes=$nodes --ntasks-per-node=$procs --cpus-per-task=$threads" >> $cfile
-#echo "#SBATCH -j oe" >> $cfile
+echo "#SBATCH --nodes=$nodes --ntasks-per-node=$procs --exclusive" >> $cfile
echo "#SBATCH --account=$accnt" >> $cfile
+echo "#SBATCH --mem=0" >> $cfile
echo "#SBATCH --partition=kjet" >> $cfile
-#echo "#SBATCH -V" >> $cfile
-#echo "#PBS -d" >> $cfile
-#. $exec >> $cfile
-#echo "/bin/sh -x $exec" >> $cfile
echo "" >>$cfile
+echo "export ntasks=$(( $nodes * $procs ))" >> $cfile
+echo "export ppn=$procs" >> $cfile
+echo "export threads=$threads" >> $cfile
echo "export OMP_NUM_THREADS=$threads" >> $cfile
+echo "ulimit -s unlimited" >> $cfile
+
echo "" >>$cfile
echo ". "$(awk '{ print $1, $2, $3, $4, $5, $6, $7, $8, $9 }' $regdir/regression_var.out) >>$cfile
echo "" >>$cfile
echo ". /apps/lmod/lmod/init/sh" >> $cfile
echo "module purge" >> $cfile
-echo "module use $gsisrc/modulefiles" >> $cfile
-echo "module load gsi_jet" >> $cfile
+echo "module use $modulefiles" >> $cfile
+echo "module load gsi_jet.intel" >> $cfile
echo "module list" >> $cfile
echo "" >>$cfile
@@ -145,40 +140,6 @@ elif [[ $verbose = YES ]];then
set -x
cat $cfile
fi
-#msub -I partition=$partition,size=$procs,walltime=$walltime $cfile
-
-#if [[ -n $when ]];then
-# whena=$when
-# if [[ $when = +* ]];then
-# hr=$(echo $when|cut -c2-3)
-# mn=$(echo $when|cut -c4-5)
-# [[ -n $mn ]] || mn=00
-# now=$(date -u +"%Y%m%d%H%M")
-# ((mn+=$(echo $now|cut -c11-12)))
-# [[ $mn -ge 60 ]] && ((hr+=1)) && ((mn-=60))
-# [[ $mn -lt 10 ]] && mn=0$mn
-# whena=$(/nwprod/util/exec/ndate +$hr $(echo $now|cut -c1-10))$mn
-# elif [[ $when = t* ]];then
-# hr=$(echo $when|cut -c2-3)
-# mn=$(echo $when|cut -c4-5)
-# [[ -n $mn ]] || mn=00
-# now=$(date -u +"%Y%m%d")
-# whena=$now$hr$mn
-# elif [[ $when = T* ]];then
-# hr=$(echo $when|cut -c2-3)
-# mn=$(echo $when|cut -c4-5)
-# [[ -n $mn ]] || mn=00
-# now=$(date -u +"%Y%m%d%H")
-# whena=$(/nwprod/util/exec/ndate +24 $now|cut -c1-8)$hr$mn
-# fi
-# yr=$(echo $whena|cut -c1-4)
-# mo=$(echo $whena|cut -c5-6)
-# dy=$(echo $whena|cut -c7-8)
-# hr=$(echo $whena|cut -c9-10)
-# mn=$(echo $whena|cut -c11-12)
-# [[ -n $mn ]] || mn=00
-# echo "#@ startdate = $mo/$dy/$yr $hr:$mn"
-#fi >>$cfile
if [[ $stdin = YES ]];then
diff --git a/ush/sub_orion b/ush/sub_orion
index 065e7c8ab0..371c30e321 100755
--- a/ush/sub_orion
+++ b/ush/sub_orion
@@ -87,6 +87,7 @@ export jobname=${jobname:-$bn}
output=${output:-$jobname.out}
myuser=$LOGNAME
myhost=$(hostname)
+exp=${jobname}
DATA=${ptmp:-/work/noaa/da/stmp/$LOGNAME/tmp}
mkdir -p $DATA
@@ -108,28 +109,31 @@ echo ""
echo "#SBATCH --output=$output" >> $cfile
echo "#SBATCH --job-name=$jobname" >> $cfile
echo "#SBATCH --qos=$queue" >> $cfile
+echo "#SBATCH --partition=$partition" >> $cfile
echo "#SBATCH --time=$timew" >> $cfile
-echo "#SBATCH --nodes=$nodes --ntasks-per-node=$procs --cpus-per-task=$threads" >> $cfile
+echo "#SBATCH --nodes=$nodes --ntasks-per-node=$procs --exclusive" >> $cfile
echo "#SBATCH --account=$accnt" >> $cfile
echo "" >>$cfile
+echo "set -x" >> $cfile
echo "export ntasks=$(( $nodes * $procs ))" >> $cfile
echo "export ppn=$procs" >> $cfile
echo "export threads=$threads" >> $cfile
echo "export OMP_NUM_THREADS=$threads" >> $cfile
-##echo "export OMP_STACKSIZE=2048M" >> $cfile
echo "ulimit -s unlimited" >> $cfile
echo "" >>$cfile
echo ". "$(awk '{ print $1, $2, $3, $4, $5, $6, $7, $8, $9 }' $regdir/regression_var.out) >>$cfile
echo "" >>$cfile
-echo ". /apps/lmod/lmod/init/sh" >> $cfile
+echo ". /apps/other/lmod/lmod/init/sh" >> $cfile
echo "module purge" >> $cfile
-echo "module use $gsisrc/modulefiles" >> $cfile
-echo "module load gsi_orion" >> $cfile
+echo "module use $modulefiles" >> $cfile
+echo "module load gsi_orion.intel" >> $cfile
echo "module list" >> $cfile
-echo "" >> $cfile
+#TODO reenable I_MPI_EXTRA_FILESYSTEM once regional ctests can properly handle parallel I/O on Orion
+echo "unset I_MPI_EXTRA_FILESYSTEM" >> $cfile
+
cat $exec >> $cfile
if [[ $nosub = YES ]];then
diff --git a/ush/sub_wcoss2 b/ush/sub_wcoss2
index 57115ef7c6..cd21e932f8 100755
--- a/ush/sub_wcoss2
+++ b/ush/sub_wcoss2
@@ -123,19 +123,14 @@ echo "" >> $cfile
echo ". "$(awk '{ print $1, $2, $3, $4, $5, $6, $7, $8, $9 }' $regdir/regression_var.out) >>$cfile
echo "" >> $cfile
-echo "module purge" >> $cfile
-echo "module load envvar/1.0" >> $cfile
-echo "module load PrgEnv-intel/8.2.0" >> $cfile
-echo "module load intel/19.1.3.304" >> $cfile
-echo "module load craype/2.7.13" >> $cfile
-echo "module load cray-mpich/8.1.12" >> $cfile
-echo "module load cray-pals/1.1.3" >> $cfile
-echo "module load prod_util/2.0.14" >> $cfile
-echo "module load prod_envir/2.0.6" >> $cfile
-echo "module load crtm/2.4.0" >> $cfile
-echo "module load cfp/2.0.4" >> $cfile
-echo "module load netcdf/4.7.4" >> $cfile
-echo "module list" >> $cfile
+echo "module reset" >> $cfile
+echo "module use $modulefiles" >> $cfile
+echo "module load gsi_wcoss2.intel" >> $cfile
+echo "module load envvar/1.0" >> $cfile
+echo "module load cray-pals/1.2.2" >> $cfile
+echo "module -t list 2>&1 | while read line;do module show $line 2>&1 | sed -n -e '2p';done | sort" >> $cfile
+echo "module avail" >> $cfile
+
echo "" >> $cfile
cat $exec >> $cfile