diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..d13458f0a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,65 @@ +--- +name: Bug report +about: Use this template for submitting bug reports. +title: "[ISSUE TITLE]" +labels: bug +assignees: +--- + + + + + +## Description + + +----- +**Screenshots** + + +----- +**Isca version** + + +----- +**System Information:** +To help us track down bugs faster, please provide the details about the machine where you run Isca. + +To do this, run the following code in Python: +```py +import platform +print(platform.uname()) +``` +and paste the output below. +```txt +# Paste system info here + +``` +----- +## Minimal reproducible example + diff --git a/.github/ISSUE_TEMPLATE/docs_issue.md b/.github/ISSUE_TEMPLATE/docs_issue.md new file mode 100644 index 000000000..c723af036 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/docs_issue.md @@ -0,0 +1,33 @@ +--- +name: Documentation issue +about: Use this template for submitting documentation-related issues. +title: "[ISSUE TITLE]" +labels: docs +assignees: +--- + + + + + +## Description + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..80845a370 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: Feature Request +about: Suggest an idea for something new to add +labels: +--- + +## Description + diff --git a/.github/ISSUE_TEMPLATE/installation_issue.md b/.github/ISSUE_TEMPLATE/installation_issue.md new file mode 100644 index 000000000..17456284d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/installation_issue.md @@ -0,0 +1,60 @@ +--- +name: Installation issue +about: Use this template if you have an issue related to installing Isca. +title: "[YOUR QUESTION]" +labels: infrastructure +assignees: +--- + + + + + +## Description + + +----- +**Screenshots** + + +----- +**Isca version** + + +----- +**System Information:** +To help us help you, provide the details about the machine where you are trying to install Isca. + +To do this, please run the following code in Python: +```py +import platform +print(platform.uname()) +``` +and paste the output below. +```txt +# Paste system info here + +``` diff --git a/.github/ISSUE_TEMPLATE/science_issue.md b/.github/ISSUE_TEMPLATE/science_issue.md new file mode 100644 index 000000000..c1980d82e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/science_issue.md @@ -0,0 +1,42 @@ +--- +name: Science issue +about: Use this template for submitting science-related issues. +title: "[YOUR QUESTION]" +labels: +assignees: +--- + + + + + +## Description + + +### Screenshots + + +## Minimal reproducible example + diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..94d4efcbe --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,85 @@ +name: docs + +on: + push: + branches: [ master ] + paths: + - '.github/workflows/docs.yml' + - 'docs/**' + - 'src/**' + +env: + GFDL_BASE: ${{ github.workspace }} + GFDL_ENV: "ubuntu_conda" + GFDL_WORK: "$HOME/gfdl_work" + GFDL_DATA: "$HOME/gfdl_data" + GFDL_PYDIR: "${{ github.workspace }}/src/extra/python" + +jobs: + docs: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + python-version: ['3.9'] + + steps: + - name: Checkout source + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + # - name: Check environment variables + # run: | + # echo "Testing" + # echo $PWD + # echo $GFDL_BASE + # echo $GFDL_PYDIR + # echo $GITHUB_WORKSPACE + # echo $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID + + - name: Setup Conda Environment + uses: conda-incubator/setup-miniconda@v2 + with: + python-version: ${{ matrix.python-version }} + environment-file: docs/environment.yml + miniforge-variant: Mambaforge + miniforge-version: "latest" + use-mamba: true + activate-environment: isca_docs + auto-activate-base: false + + - name: List installed packages + shell: bash -l {0} + run: conda list + + - name: Install + shell: bash -l {0} + run: | + cd $GFDL_PYDIR + python -m pip install -e . + cd $GFDL_BASE + + - name: Build docs + shell: bash -l {0} + run: | + cd docs/ + make html -e + + - name: Commit documentation changes + run: | + git clone https://github.com/$GITHUB_REPOSITORY.git --branch gh-pages --single-branch gh-pages + cp -r docs/_build/html/* gh-pages/ + cd gh-pages + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add . + git commit -m "Update documentation" -a || true + # The above command will fail if no changes were present, so we ignore that. + + - name: Push changes + uses: ad-m/github-push-action@master + with: + branch: gh-pages + directory: gh-pages + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 000000000..ee29f791d --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,70 @@ +name: tests + +on: + push: + branches: [ master ] + paths: + - '.github/workflows/tests.yml' + - 'bin/**' + - 'bin/**' + - 'ci/**' + - 'exp/**' + - 'input/**' + - 'src/**' + - 'test/**' + pull_request: + branches: [ master ] + paths: + - '.github/workflows/tests.yml' + - 'bin/**' + - 'ci/**' + - 'exp/**' + - 'input/**' + - 'src/**' + - 'test/**' + +env: + GFDL_BASE: ${{ github.workspace }} + GFDL_ENV: "ubuntu_conda" + GFDL_WORK: "${{ github.workspace }}/../gfdl_work" + GFDL_DATA: "${{ github.workspace }}/../gfdl_data" + GFDL_PYDIR: "${{ github.workspace }}/src/extra/python" + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] # , macos-latest] + python-version: ['3.12'] + + steps: + - name: Checkout source + uses: actions/checkout@v2 + + - name: Setup Conda for OS ${{ matrix.os }} and Python ${{ matrix.python-version }} + uses: conda-incubator/setup-miniconda@v2 + with: + python-version: ${{ matrix.python-version }} + environment-file: ci/environment-py${{ matrix.python-version }}_frozen.yml + miniforge-variant: Mambaforge + miniforge-version: "latest" + use-mamba: true + activate-environment: isca_env + auto-activate-base: false + + - name: Install + shell: bash -l {0} + run: | + cd $GFDL_PYDIR + python -m pip install -e . + cd $GFDL_BASE + + - name: List installed packages + shell: bash -l {0} + run: conda list + + - name: Run tests + shell: bash -l {0} + run: | + python -m pytest diff --git a/.gitignore b/.gitignore index 4333c2fac..3b7c89055 100644 --- a/.gitignore +++ b/.gitignore @@ -1,31 +1,115 @@ -exec.*/ +# Project-specific compilation*/ -*.x -*.o -*~ -~* -spin_up_restart/ -nohup.out -Makefile -old_exps -opt_exps -frierson_comparison_*old* -*.pyc +docs/source/examples/index.rst +exec.*/ exp/st_test* exp/archived/* -*.DS_Store -*.egg-info -._* -*.mod +frierson_comparison_*old* +*land_world_mountains.nc +mima_pz.txt +*output.txt +old_exps +opt_exps postprocessing/plevel_interpolation/scripts/*.nc postprocessing/plevel_interpolation/scripts/*.nml postprocessing/plevel_interpolation/scripts/archived/* -*land_world_mountains.nc -*output.txt +spin_up_restart/ src/extra/python/scripts/*.nc src/extra/python/scripts/archived/ -mima_pz.txt *.sh.* src/atmos_param/socrates/src/trunk* + +# Temporary files +*.x +*.o +*~ +~* +nohup.out +Makefile +!docs/Makefile +*.DS_Store +._* +*.mod + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +pip-wheel-metadata/ + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ test/.cache test/results.xml +*.sh.e* +*.sh.o* + +# Translations +*.mo +*.pot + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter +Untitled*.ipynb +.ipynb_checkpoints + +# pyenv +.python-version + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# mkdocs documentation +/site diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 000000000..27dc52038 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,38 @@ +cff-version: 1.1.0 +authors: + - family-names: Vallis + given-names: Geoffrey K. + orcid: https://orcid.org/0000-0002-5971-8995 + - family-names: Colyer + given-names: Greg + - family-names: Geen + given-names: Ruth + - family-names: Gerber + given-names: Edwin + orcid: https://orcid.org/0000-0002-6010-6638 + - family-names: Jucker + given-names: Martin + orcid: https://orcid.org/0000-0002-4227-315X + - family-names: Maher + given-names: Penelope + orcid: https://orcid.org/0000-0001-8513-8700 + - family-names: Paterson + given-names: Alexander + - family-names: Pietschnig + given-names: Marianne + orcid: https://orcid.org/0000-0002-7405-5536 + - family-names: Penn + given-names: James + - family-names: Thomson + given-names: Stephen I. + orcid: https://orcid.org/0000-0002-4775-3259 +title: "Isca, v1.0: a framework for the global modelling of the atmospheres of Earth and other planets at varying levels of complexity" +journal: Geoscientific Model Development +volume: 11 +year: 2018 +number: 3 +pages: 843--859 +version: v1.0 +doi: 10.5194/gmd-11-843-2018 +url: https://gmd.copernicus.org/articles/11/843/2018/ +date-released: 2018-03-06 diff --git a/ReadMe.md b/ReadMe.md index c071cbd0e..46dbc6359 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,4 +1,31 @@ -# Isca +

+ Contact: Isaac Held + Reviewers: Peter Phillipps ++ + + +
+ A spectral transform model for two-dimensional, non-divergent flow on the + surface of the sphere. ++ + + +
+ Integrates the barotropic vorticity equation for nondivergent flow on the + sphere using the spectral transform technique. Also allows for the + inclusion of a passive tracer advected by the same spectral advection + algorithm as the vorticity, and a gridpoint tracer advected with a finite + volume algorithm on the transform grid. The default initial condition + provided as an example is a zonal flow resembling that in the Northern + winter, plus a sinusoidal disurbance localized in midlatitudes. + + For a full description of the model and algorithms used, see barotropic.ps + + The interfaces in this module are the generic intefaces required by the + main program that can be used to drive various idealized atmospheric + models within FMS. Model resolution and related paramters are set in + namelists within the modules barotropic_xxx. ++ + + +
+ fms_mod + constants_mod + transforms_mod + time_manager_mod + diag_manager_mod + barotropic_dynamics_mod + barotropic_physics_mod + barotopic_diagnostics_mod ++ + + +
+ + use atmosphere_mod [,only: atmosphere_init, + atmosphere, + atmosphere_end] + ++ + + +
+ + There are no pubic data types + ++ + + +
+ +subroutine atmosphere_init. Initializes the model. +subroutine atmosphere. Integrates forward one time step +subroutine atmosphere_end. Terminates model, cleaning up memory and finalizing diagnostics. + + ++ + ++ + subroutine atmosphere_init(Time_init, Time, Time_step) + + input: + + type(time_type) :: Time_init -- Initial model time + + type(time_type) :: Time -- Model time + + type(time_type) :: Time_step -- Time step + + When Time=Time_init, the first time step is a forward + step rather than leap frog because a cold start is assumed. + + The FMS main program that runs the solo atmospheric models + obtains Time_init from the diag_table and Time from its namelist. + ++
+ + + subroutine atmosphere(Time) + + input: + + type(time_type) :: Time -- Model time + + Integrates forward one time step + + +
+ + subroutine atmosphere_end(Atmos) + + No calling arguments. + + Terminates model, cleaning up memory and finalizing diagnostics + + +
+
+&atmosphere_nml + + print_interval, integer : time interval in seconds + between prints of global mean energy and enstrophy to standard output ++ + + +
+ + Fatal error message if any public routine is called prior to atmosphere_init + ++ + + +
+ Contact: Isaac Held + Reviewers: Peter Phillipps + ++ + + +
+ + The diagnostics module for the model that solves the barotropic vorticity + equation on the sphere + ++ + + +
+ + Using the diagnostics manager, creates output files for the barotropic model. + Variables currently available for output are + zonal wind + meridional wind + relative vorticity + absolute vorticity + streamfunction + spectral tracer in grid domain + grid tracer + + Whether or not these fields are actually output, the location of the + output, the frequency of output, whether or not the output is averaged + in time or an instantaneous snapshot, is controlled by a + diag_table file utilized by the diagnostics manager module + + One can add other diagnostics by following the (somewhat convoluted) + pattern within the program + + ++ + + +
+ + diag_manaager_mod + transforms_mod + time_manager_mod + barotropic_dynamics_mod + barotropic_physics_mod + ++ + + +
+ + use barotropic_diagnostics_mod [,only: barotropic_diagnostics_init, + barotropic_diagnostics] + ++ + + + +
+ +subroutine barotropic_diagnostics_init +subroutine barotropic_diagnostics + + ++ + subroutine barotropic_diagnostics_init(Time, num_lon, num_lat) + + type(time_type) , intent(in) :: Time + current time + integer, intent(in) :: num_lon, num_lat + num_lon = number of longitudes in global domain + num_lat = number of latitudes in global domain + + + Initializes module + ++ +
+ + + + subroutine barotropic_diagnostics (Time, Grid, Phys, time_index) + + type(time_type), intent(in) :: Time + type(phys_type), intent(in) :: Phys + type(grid_type), intent(in) :: Grid + integer, intent(in) :: time_index + + phys_type is defined in barotropic_physics_mod; + Phys is currently empty as there is no information generated in + barotropic_physics_mod to be output; + + grid_type is defined in barotropic_dynamics_mod: + Grid contains all of the fields to be output + + many of the grid fields in grid_type are dimensioned (lon, lat, time_index) + where time_index = 1 or 2 -- the two time levels needed to update the + state of the model using a leapfrog step are toggled between (:,:,1) + and (:,:,2). The input time_index (which must equal either 1 or 2) + determines which of these two fields is output) + + (this is confusing -- the calling program needs to know what has + been placed in which slot -- it would be better to store this + information within the data type) + + + + +
+ + + diff --git a/src/atmos_spectral_barotropic/barotropic_dynamics.F90 b/src/atmos_spectral_barotropic/barotropic_dynamics.F90 new file mode 100644 index 000000000..ac18b6127 --- /dev/null +++ b/src/atmos_spectral_barotropic/barotropic_dynamics.F90 @@ -0,0 +1,574 @@ +module barotropic_dynamics_mod + +!----------------------------------------------------------------------- +! GNU General Public License +! +! This program is free software; you can redistribute it and/or modify it and +! are expected to follow the terms of the GNU General Public License +! as published by the Free Software Foundation; either version 2 of +! the License, or (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, but WITHOUT +! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +! License for more details. +! +! For the full text of the GNU General Public License, +! write to: Free Software Foundation, Inc., +! 675 Mass Ave, Cambridge, MA 02139, USA. +! or see: http://www.gnu.org/licenses/gpl.html +!----------------------------------------------------------------------- + +use fms_mod, only: open_namelist_file, & + open_restart_file, & + file_exist, & + check_nml_error, & + error_mesg, & + mpp_error, & + FATAL, WARNING, & + write_version_number, & + mpp_pe, & + mpp_root_pe, & + read_data, & + write_data, & + set_domain, & + close_file, & + stdlog + +use time_manager_mod, only : time_type, & + get_time, & + operator(==), & + operator(-) + +use constants_mod, only: radius, omega + +use transforms_mod, only: transforms_init, transforms_end, & + get_grid_boundaries, & + trans_spherical_to_grid, trans_grid_to_spherical, & + compute_laplacian, & + get_sin_lat, get_cos_lat, & + get_deg_lon, get_deg_lat, & + get_grid_domain, get_spec_domain, & + spectral_domain, grid_domain, & + vor_div_from_uv_grid, uv_grid_from_vor_div, & + horizontal_advection + +use spectral_damping_mod, only: spectral_damping_init, & + compute_spectral_damping + +use leapfrog_mod, only: leapfrog + +use fv_advection_mod, only: fv_advection_init, & + a_grid_horiz_advection + +use stirring_mod, only: stirring, stirring_end + +!=============================================================================================== +implicit none +private +!=============================================================================================== + +public :: barotropic_dynamics_init, & + barotropic_dynamics, & + barotropic_dynamics_end, & + dynamics_type, & + grid_type, & + spectral_type, & + tendency_type + + +! version information +!=================================================================== +character(len=128) :: version = '$Id: barotropic_dynamics.F90,v 17.0 2009/07/21 03:00:21 fms Exp $' +character(len=128) :: tagname = '$Name: siena_201207 $' +!=================================================================== + +type grid_type + real, pointer, dimension(:,:,:) :: u=>NULL(), v=>NULL(), vor=>NULL(), trs=>NULL(), tr=>NULL() + real, pointer, dimension(:,:) :: pv=>NULL(), stream=>NULL() + real, pointer, dimension(:) :: zonal_u_init=>NULL() +end type +type spectral_type + complex, pointer, dimension(:,:,:) :: vor=>NULL(), trs=>NULL() +end type +type tendency_type + real, pointer, dimension(:,:) :: u=>NULL(), v=>NULL(), trs=>NULL(), tr=>NULL() +end type +type dynamics_type + type(grid_type) :: grid + type(spectral_type) :: spec + type(tendency_type) :: tend + integer :: num_lon, num_lat + logical :: grid_tracer, spec_tracer +end type + +integer, parameter :: num_time_levels = 2 + +integer :: is, ie, js, je, ms, me, ns, ne + +logical :: module_is_initialized = .false. + +real, allocatable, dimension(:) :: sin_lat, cos_lat, rad_lat, rad_lon, & + deg_lat, deg_lon, & + coriolis, glon_bnd, glat_bnd + +integer :: pe, npes + +! namelist parameters with default values + +logical :: check_fourier_imag = .false. +logical :: south_to_north = .true. +logical :: triang_trunc = .true. + +real :: robert_coeff = 0.04 +real :: longitude_origin = 0.0 +real :: raw_filter_coeff = 1.0 + +character(len=64) :: damping_option = 'resolution_dependent' +integer :: damping_order = 4 +real :: damping_coeff = 1.e-04 +real :: damping_coeff_r = 0.0 + +real :: zeta_0 = 8.e-05 +integer :: m_0 = 4 +real :: eddy_width = 15.0 +real :: eddy_lat = 45.0 + +logical :: spec_tracer = .true. +logical :: grid_tracer = .true. + +integer :: num_lat = 128 +integer :: num_lon = 256 +integer :: num_fourier = 85 +integer :: num_spherical = 86 +integer :: fourier_inc = 1 +integer :: cutoff_wn = 30 + +real, dimension(2) :: valid_range_v = (/-1.e3,1.e3/) +character(len=64) :: initial_zonal_wind = 'two_jets' + +namelist /barotropic_dynamics_nml/ check_fourier_imag, south_to_north, & + triang_trunc, & + num_lon, num_lat, num_fourier, & + num_spherical, fourier_inc, & + longitude_origin, damping_option, & + damping_order, damping_coeff, & + damping_coeff_r, robert_coeff, & + spec_tracer, grid_tracer, & + eddy_lat, eddy_width, zeta_0, m_0, & + valid_range_v, initial_zonal_wind, & + cutoff_wn + +contains + +!=============================================================================================== + +subroutine barotropic_dynamics_init (Dyn, Time, Time_init, dt_real) + +type(dynamics_type), intent(inout) :: Dyn +type(time_type) , intent(in) :: Time, Time_init +real, intent(in) :: dt_real + +integer :: i, j + +real, allocatable, dimension(:) :: glon_bnd, glat_bnd +complex, allocatable, dimension(:,:) :: div +real :: xx, yy, dd + +integer :: ierr, io, unit, pe +logical :: root + +! < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > + +call write_version_number (version, tagname) + +pe = mpp_pe() +root = (pe == mpp_root_pe()) + +if (file_exist('input.nml')) then + unit = open_namelist_file () + ierr=1 + do while (ierr /= 0) + read (unit, nml=barotropic_dynamics_nml, iostat=io, end=10) + ierr = check_nml_error (io, 'barotropic_dynamics_nml') + enddo + 10 call close_file (unit) +endif + + +if (root) write (stdlog(), nml=barotropic_dynamics_nml) + +call transforms_init(radius, num_lat, num_lon, num_fourier, fourier_inc, num_spherical, & + south_to_north=south_to_north, & + triang_trunc=triang_trunc, & + longitude_origin=longitude_origin ) + +call get_grid_domain(is,ie,js,je) +call get_spec_domain(ms,me,ns,ne) + +Dyn%num_lon = num_lon +Dyn%num_lat = num_lat +Dyn%spec_tracer = spec_tracer +Dyn%grid_tracer = grid_tracer + +allocate (sin_lat (js:je)) +allocate (cos_lat (js:je)) +allocate (deg_lat (js:je)) +allocate (deg_lon (is:ie)) +allocate (rad_lat (js:je)) +allocate (rad_lon (is:ie)) +allocate (coriolis (js:je)) + +allocate (glon_bnd (num_lon + 1)) +allocate (glat_bnd (num_lat + 1)) + +call get_deg_lon (deg_lon) +call get_deg_lat (deg_lat) +call get_sin_lat (sin_lat) +call get_cos_lat (cos_lat) +call get_grid_boundaries (glon_bnd, glat_bnd, global=.true.) + +coriolis = 2*omega*sin_lat + +rad_lat = deg_lat*atan(1.0)/45.0 +rad_lon = deg_lon*atan(1.0)/45.0 + +call spectral_damping_init(damping_coeff, damping_order, damping_option, cutoff_wn, num_fourier, num_spherical, 1, 0., 0., 0., & + damping_coeff_r=damping_coeff_r) + +allocate (Dyn%spec%vor (ms:me, ns:ne, num_time_levels)) +allocate (Dyn%grid%u (is:ie, js:je, num_time_levels)) +allocate (Dyn%grid%v (is:ie, js:je, num_time_levels)) +allocate (Dyn%grid%vor (is:ie, js:je, num_time_levels)) + +allocate (Dyn%tend%u (is:ie, js:je)) +allocate (Dyn%tend%v (is:ie, js:je)) +allocate (Dyn%grid%stream (is:ie, js:je)) +allocate (Dyn%grid%pv (is:ie, js:je)) +allocate (Dyn%grid%zonal_u_init(js:je)) + +allocate (div (ms:me, ns:ne)) + +call fv_advection_init(num_lon, num_lat, glat_bnd, 360./float(fourier_inc)) +if(Dyn%grid_tracer) then + allocate(Dyn%Grid%tr (is:ie, js:je, num_time_levels)) + allocate(Dyn%Tend%tr (is:ie, js:je)) +endif + +if(Dyn%spec_tracer) then + allocate(Dyn%Grid%trs (is:ie, js:je, num_time_levels)) + allocate(Dyn%Tend%trs (is:ie, js:je)) + allocate(Dyn%Spec%trs (ms:me, ns:ne, num_time_levels)) +endif + +if(trim(initial_zonal_wind) == 'zero') then + Dyn%grid%zonal_u_init = 0.0 +else if(trim(initial_zonal_wind) == 'two_jets') then + do j = js, je + Dyn%grid%zonal_u_init(j) = 25.0*cos_lat(j) & + - 30.0*(cos_lat(j)**3) & + + 300.0*(sin_lat(j)**2)*(cos_lat(j)**6) + enddo +else + call error_mesg('barotropic_dynamics_init',trim(initial_zonal_wind)// & + ' is not a valid value of initial_zonal_wind ', FATAL) +endif + +if(Time == Time_init) then + + do j = js, je + Dyn%Grid%u(:,j,1) = Dyn%grid%zonal_u_init(j) + Dyn%Grid%v(:,j,1) = 0.0 + end do + + call vor_div_from_uv_grid(Dyn%Grid%u (:,:,1), Dyn%Grid%v (:,:,1), & + Dyn%Spec%vor(:,:,1), div) + + call trans_spherical_to_grid(Dyn%Spec%vor(:,:,1), Dyn%Grid%vor(:,:,1)) + + do j = js, je + do i = is, ie + yy = (deg_lat(j)- eddy_lat)/eddy_width + Dyn%Grid%vor(i,j,1) = Dyn%Grid%vor(i,j,1) + & + 0.5*zeta_0*cos_lat(j)*exp(-yy*yy)*cos(m_0*rad_lon(i)) + end do + end do + + call trans_grid_to_spherical(Dyn%Grid%vor(:,:,1), Dyn%Spec%vor(:,:,1)) + + div = (0.,0.) + call uv_grid_from_vor_div (Dyn%Spec%vor(:,:,1), div, & + Dyn%Grid%u (:,:,1), Dyn%Grid%v (:,:,1)) + + if(Dyn%grid_tracer) then + Dyn%Grid%tr = 0.0 + do j = js, je + if(deg_lat(j) > 10.0 .and. deg_lat(j) < 20.0) Dyn%Grid%tr(:,j,1) = 1.0 + if(deg_lat(j) > 70.0 ) Dyn%Grid%tr(:,j,1) = -1.0 + end do + endif + + if(Dyn%spec_tracer) then + Dyn%Grid%trs = 0.0 + do j = js, je + if(deg_lat(j) > 10.0 .and. deg_lat(j) < 20.0) Dyn%Grid%trs(:,j,1) = 1.0 + if(deg_lat(j) > 70.0 ) Dyn%Grid%trs(:,j,1) = -1.0 + end do + call trans_grid_to_spherical(Dyn%Grid%trs(:,:,1), Dyn%Spec%trs(:,:,1)) + endif + +else + + call read_restart(Dyn) + +endif + +module_is_initialized = .true. + +return +end subroutine barotropic_dynamics_init + +!=============================================================================================== + +subroutine barotropic_dynamics(Time, Time_init, Dyn, previous, current, future, delta_t) + +type(time_type) , intent(in) :: Time, Time_init +type(dynamics_type), intent(inout) :: Dyn +integer, intent(in ) :: previous, current, future +real, intent(in ) :: delta_t + +! < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > + +complex, dimension(ms:me, ns:ne) :: dt_vors, dt_divs, stream, zeros, spec_diss +real, dimension(is:ie, js:je) :: dt_vorg +integer :: j, seconds, days + +! < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > + +if(.not.module_is_initialized) then + call error_mesg('barotropic_dynamics','dynamics has not been initialized ', FATAL) +endif + +zeros = (0.,0.) + +do j = js, je + Dyn%grid%pv(:,j) = Dyn%grid%vor(:,j,current) + coriolis(j) +end do + +Dyn%Tend%u = Dyn%Tend%u + Dyn%grid%pv*Dyn%Grid%v(:,:,current) +Dyn%Tend%v = Dyn%Tend%v - Dyn%grid%pv*Dyn%Grid%u(:,:,current) + +call vor_div_from_uv_grid (Dyn%Tend%u, Dyn%Tend%v, dt_vors, dt_divs) + +call compute_spectral_damping(Dyn%Spec%vor(:,:,previous), dt_vors, delta_t) + +call stirring(Time, dt_vors) + +call leapfrog(Dyn%Spec%vor , dt_vors , previous, current, future, delta_t, robert_coeff, raw_filter_coeff) + +call trans_spherical_to_grid(Dyn%Spec%vor(:,:,future), Dyn%Grid%vor(:,:,future)) + +call uv_grid_from_vor_div (Dyn%Spec%vor (:,:,future), zeros, & + Dyn%Grid%u (:,:,future), Dyn%Grid%v (:,:,future)) + +if(minval(Dyn%Grid%v) < valid_range_v(1) .or. maxval(Dyn%Grid%v) > valid_range_v(2)) then + call get_time (Time, seconds, days) + call mpp_error(FATAL,'barotropic_dynamics: Meridional wind out of valid range. Model time=',days,' days ',seconds,' seconds') +endif + +if(Dyn%spec_tracer) call update_spec_tracer(Dyn%Spec%trs, Dyn%Grid%trs, Dyn%Tend%trs, & + Dyn%Grid%u, Dyn%Grid%v, previous, current, future, delta_t) + +if(Dyn%grid_tracer) call update_grid_tracer(Dyn%Grid%tr, Dyn%Tend%tr, & + Dyn%Grid%u, Dyn%Grid%v, previous, current, future, delta_t) + +stream = compute_laplacian(Dyn%Spec%vor(:,:,current), -1) +call trans_spherical_to_grid(stream, Dyn%grid%stream) + +return +end subroutine barotropic_dynamics + +!=================================================================================== + +subroutine update_spec_tracer(tr_spec, tr_grid, dt_tr, ug, vg, & + previous, current, future, delta_t) + +complex, intent(inout), dimension(ms:me, ns:ne, num_time_levels) :: tr_spec +real , intent(inout), dimension(is:ie, js:je, num_time_levels) :: tr_grid +real , intent(inout), dimension(is:ie, js:je ) :: dt_tr +real , intent(in ), dimension(is:ie, js:je, num_time_levels) :: ug, vg +real , intent(in ) :: delta_t +integer, intent(in ) :: previous, current, future + +complex, dimension(ms:me, ns:ne) :: dt_trs + +call horizontal_advection (tr_spec(:,:,current), ug(:,:,current), vg(:,:,current), dt_tr) +call trans_grid_to_spherical (dt_tr, dt_trs) +call compute_spectral_damping (tr_spec(:,:,previous), dt_trs, delta_t) +call leapfrog (tr_spec, dt_trs, previous, current, future, delta_t, robert_coeff, raw_filter_coeff) +call trans_spherical_to_grid (tr_spec(:,:,future), tr_grid(:,:,future)) + +return +end subroutine update_spec_tracer +!========================================================================== + +subroutine update_grid_tracer(tr_grid, dt_tr_grid, ug, vg, & + previous, current, future, delta_t) + +real , intent(inout), dimension(is:ie, js:je, num_time_levels) :: tr_grid +real , intent(inout), dimension(is:ie, js:je ) :: dt_tr_grid +real , intent(in ), dimension(is:ie, js:je, num_time_levels) :: ug, vg + +real , intent(in ) :: delta_t +integer, intent(in ) :: previous, current, future + +real, dimension(size(tr_grid,1),size(tr_grid,2)) :: tr_current, tr_future + +tr_future = tr_grid(:,:,previous) + delta_t*dt_tr_grid +dt_tr_grid = 0.0 +call a_grid_horiz_advection (ug(:,:,current), vg(:,:,current), tr_future, delta_t, dt_tr_grid) +tr_future = tr_future + delta_t*dt_tr_grid +tr_current = tr_grid(:,:,current) + & + robert_coeff*(tr_grid(:,:,previous) + tr_future - 2.0*tr_grid(:,:,current)) +tr_grid(:,:,current) = tr_current +tr_grid(:,:,future) = tr_future + +return +end subroutine update_grid_tracer + +!========================================================================== + +subroutine read_restart(Dyn) + +type(dynamics_type), intent(inout) :: Dyn + +integer :: unit, m, n, nt +real, dimension(ms:me, ns:ne) :: real_part, imag_part + +if(file_exist('INPUT/barotropic_dynamics.res.nc')) then + do nt = 1, 2 + call read_data('INPUT/barotropic_dynamics.res.nc', 'vors_real', real_part, spectral_domain, timelevel=nt) + call read_data('INPUT/barotropic_dynamics.res.nc', 'vors_imag', imag_part, spectral_domain, timelevel=nt) + do n=ns,ne + do m=ms,me + Dyn%Spec%vor(m,n,nt) = cmplx(real_part(m,n),imag_part(m,n)) + end do + end do + if(Dyn%spec_tracer) then + call read_data('INPUT/barotropic_dynamics.res.nc', 'trs_real', real_part, spectral_domain, timelevel=nt) + call read_data('INPUT/barotropic_dynamics.res.nc', 'trs_imag', imag_part, spectral_domain, timelevel=nt) + do n=ns,ne + do m=ms,me + Dyn%Spec%trs(m,n,nt) = cmplx(real_part(m,n),imag_part(m,n)) + end do + end do + endif + call read_data('INPUT/barotropic_dynamics.res.nc', 'u', Dyn%Grid%u (:,:,nt), grid_domain, timelevel=nt) + call read_data('INPUT/barotropic_dynamics.res.nc', 'v', Dyn%Grid%v (:,:,nt), grid_domain, timelevel=nt) + call read_data('INPUT/barotropic_dynamics.res.nc', 'vor', Dyn%Grid%vor(:,:,nt), grid_domain, timelevel=nt) + if(Dyn%spec_tracer) then + call read_data('INPUT/barotropic_dynamics.res.nc', 'trs', Dyn%Grid%trs(:,:,nt), grid_domain, timelevel=nt) + endif + if(Dyn%grid_tracer) then + call read_data('INPUT/barotropic_dynamics.res.nc', 'tr', Dyn%Grid%tr(:,:,nt), grid_domain, timelevel=nt) + endif + end do +else if(file_exist('INPUT/barotropic_dynamics.res')) then + unit = open_restart_file(file='INPUT/barotropic_dynamics.res',action='read') + + do nt = 1, 2 + call set_domain(spectral_domain) + call read_data(unit,Dyn%Spec%vor(:,:, nt)) + if(Dyn%spec_tracer) call read_data(unit,Dyn%Spec%trs(:,:, nt)) + + call set_domain(grid_domain) + call read_data(unit,Dyn%Grid%u (:,:, nt)) + call read_data(unit,Dyn%Grid%v (:,:, nt)) + call read_data(unit,Dyn%Grid%vor (:,:, nt)) + if(Dyn%spec_tracer) call read_data(unit,Dyn%Grid%trs(:,:, nt)) + if(Dyn%grid_tracer) call read_data(unit,Dyn%Grid%tr (:,:, nt)) + + end do + call close_file(unit) + +else + call error_mesg('read_restart', 'restart does not exist', FATAL) +endif + +return +end subroutine read_restart + +!==================================================================== + +subroutine write_restart(Dyn, previous, current) + +type(dynamics_type), intent(in) :: Dyn +integer, intent(in) :: previous, current + +integer :: unit, nt, nn + +do nt = 1, 2 + if(nt == 1) nn = previous + if(nt == 2) nn = current + call write_data('RESTART/barotropic_dynamics.res.nc', 'vors_real', real(Dyn%Spec%vor(:,:,nn)), spectral_domain) + call write_data('RESTART/barotropic_dynamics.res.nc', 'vors_imag', aimag(Dyn%Spec%vor(:,:,nn)), spectral_domain) + if(Dyn%spec_tracer) then + call write_data('RESTART/barotropic_dynamics.res.nc', 'trs_real', real(Dyn%Spec%trs(:,:,nn)), spectral_domain) + call write_data('RESTART/barotropic_dynamics.res.nc', 'trs_imag', aimag(Dyn%Spec%trs(:,:,nn)), spectral_domain) + endif + call write_data('RESTART/barotropic_dynamics.res.nc', 'u', Dyn%Grid%u (:,:,nn), grid_domain) + call write_data('RESTART/barotropic_dynamics.res.nc', 'v', Dyn%Grid%v (:,:,nn), grid_domain) + call write_data('RESTART/barotropic_dynamics.res.nc', 'vor', Dyn%Grid%vor(:,:,nn), grid_domain) + if(Dyn%spec_tracer) then + call write_data('RESTART/barotropic_dynamics.res.nc', 'trs', Dyn%Grid%trs(:,:,nn), grid_domain) + endif + if(Dyn%grid_tracer) then + call write_data('RESTART/barotropic_dynamics.res.nc', 'tr', Dyn%Grid%tr(:,:,nn), grid_domain) + endif +enddo + +!unit = open_restart_file(file='RESTART/barotropic_dynamics.res', action='write') + +!do nt = 1, 2 +! if(nt == 1) nn = previous +! if(nt == 2) nn = current + +! call set_domain(spectral_domain) +! call write_data(unit,Dyn%Spec%vor(:,:, nn)) +! if(Dyn%spec_tracer) call write_data(unit,Dyn%Spec%trs(:,:, nn)) + +! call set_domain(grid_domain) +! call write_data(unit,Dyn%Grid%u (:,:, nn)) +! call write_data(unit,Dyn%Grid%v (:,:, nn)) +! call write_data(unit,Dyn%Grid%vor (:,:, nn)) +! if(Dyn%spec_tracer) call write_data(unit,Dyn%Grid%trs(:,:, nn)) +! if(Dyn%grid_tracer) call write_data(unit,Dyn%Grid%tr (:,:, nn)) +!end do + +!call close_file(unit) + +end subroutine write_restart + +!==================================================================== + +subroutine barotropic_dynamics_end (Dyn, previous, current) + +type(dynamics_type), intent(inout) :: Dyn +integer, intent(in) :: previous, current + +if(.not.module_is_initialized) then + call error_mesg('barotropic_dynamics','dynamics has not been initialized ', FATAL) +endif + +call transforms_end() +call stirring_end() + +call write_restart (Dyn, previous, current) + +module_is_initialized = .false. + +return +end subroutine barotropic_dynamics_end +!=================================================================================== + +end module barotropic_dynamics_mod diff --git a/src/atmos_spectral_barotropic/barotropic_dynamics.html b/src/atmos_spectral_barotropic/barotropic_dynamics.html new file mode 100644 index 000000000..62c97898a --- /dev/null +++ b/src/atmos_spectral_barotropic/barotropic_dynamics.html @@ -0,0 +1,371 @@ + +module barotropic_dynamics_mod + + +
+ + +module barotropic_dynamics_mod
+ + ++ Contact: Isaac Held + Reviewers: Peter Phillipps + ++ + + +
+OVERVIEW
+ ++ + The dynamical core of the spectral transform model for + two-dimensional, non-divergent flow on the surface of the sphere. + ++ + + +
+DESCRIPTION
+ ++ + Integrates the barotropic vorticity equation for nondivergent flow on the + sphere using the spectral transform technique. Also allows for the + inclusion of a passive tracer advected by the same spectral advection + algorithm as the vorticity, and a gridpoint tracer advected with a finite + volume algorithm on the transform grid. The default initial condition + provided as an example is a zonal flow resembling that in the Northern + winter, plus a sinusoidal disurbance localized in midlatitudes. + + For a full description of the model and algorithms used, see + barotropic.ps + + For higher level routines for running this barotropic spectral model, + see atmosphere_mod + + ++ + + +
+OTHER MODULES USED
+ ++ + fms_mod + constants_mod + time_manager_mod + transforms_mod + spectral_damping_mod + leapfrog_mod + fv_advection_mod + ++ + + +
+PUBLIC INTERFACE
+ ++ + use barotropic_dynamics_mod [,only: barotropic_dynamics_init, + barotropic_dynamics, + barotropic_dynamics_end, + dynamics_type, + grid_type, + spectral_type, + tendency_type] + ++ + + +
+PUBLIC DATA
+ ++ ++ + + +
+ + +type grid_type + real, pointer, dimension(:,:,:) :: u, v, vor, trs, tr, pv + real, pointer, dimension(:,:) :: stream +end type + + allocated space for grid fields + + (:,:,:) => (lon, lat, time_level) + (:,:) => (lon, lat) + (lon, lat) on local computational domain + time_level stores the two time levels needed for the + leapfrog step + + u -- eastward velocity (m/s) + v -- northward velocity (m/s) + vor -- vorticity (1/s) + trs -- tracer advected spectrally + tr -- tracer advected on grid + pv -- absolute vorticity, f + vor, where f = 2*omega*sin(lat) (1/s) + stream -- streamfunction (m^2/s) at current time + + + +
+ + +type spectral_type + complex, pointer, dimension(:,:,:) :: vor, trs +end type + + allocated space for spectral fields + + (:,:,:) => (zonal, meridional, time_level) + + vor -- spectral vorticity + trs -- spectral tracer + +
+ + +type tendency_type + real, pointer, dimension(:,:) :: u, v, trs, tr +end type + + allocated space for accumulating tendencies, d/dt, in grid space, + for prognostic variables + + (:,:,:) => (lon, lat) + +
+ + +type dynamics_type + type(grid_type) :: grid + type(spectral_type) :: spec + type(tendency_type) :: tend + integer :: num_lon, num_lat ! size of global domain + logical :: grid_tracer, spec_tracer +end type + + grid_tracer = .true. => tracer with gridpoint advection is beign integrated + similarly for spec_tracer + +
+ +
+PUBLIC ROUTINES
+ ++ +subroutine barotropic_dynamics_init +subroutine barotropic _dynamics +subroutine barotropic_dynamics_end +type (grid_type) +type (spectral_type) +type (tendency_type) +type (dynamics_type) + + + ++ + + ++ + subroutine barotropic_dynamics_init(Dyn, Time, Time_init) + + type(dynamics_type), intent(inout) :: Dyn + type containing all dynamical fields and related information + (see type (dynamics_type)) + + type(time_type) , intent(in) :: Time, Time_init + current time and time at which integeration began + time_type defined by time_manager_mod + + + Initializes the module; + Reads restart from 'INPUT/barotropic_dynamics.res' if Time = Time_init; + otherwise uses default initial conditions + ++ +
+ + + + subroutine barotropic_dynamics & + (Time, Time_init, Dyn, previous, current, future, delta_t) + + type(time_type) , intent(inout) :: Time, Time_init + type(dynamics_type), intent(inout) :: Dyn + integer , intent(in ) :: previous, current, future + real , intent(in ) :: delta_t + + previous, current and future = 1 or 2 + these integers refer to the third dimension of the + three-dimensional fields in Dyn + the fields at time t - delta_t are assumed to be in (:,:,previous) + the fields at time t are assumed to be in (:,:,current) + the fields at time t + delta_t are placed in (:,:,future) + overwriting whatever is already there + + delta_t = time step in seconds + + updates dynamical fields by one time step + + + +
+ + + subroutine barotropic_dynamics_end(Dyn, previous, current) + + type(dynamics_type), intent(inout) :: Dyn + integer, intent(in) :: previous, current + + + Terminates module; + writes restart file to 'RESTART/barotropic_dynamics.res' + + + + +
+
+NAMELIST
+ ++ +&barotropic_dynamics_nml + + integer :: num_lat = 128 + number of latitudes in global grid + + integer :: num_lon = 256 + number of longitudes in global grid + should equal 2*num_lat for Triangular truncation + + integer :: num_fourier = 85 + the retained fourier wavenumber are n*fourier_inc, where + n ranges from 0 to num_fourier + + integer :: num_spherical = 86 + the maximum number of meridional modes for any zonal wavenumber + for triangular truncation, set num_spherical = num_fourier +1 + + integer :: fourier_inc = 1 + creates a "sector" model if fourier_inc > 1; integration domain is + (360 degrees longitude)/fourier_inc + + (the default values listed above define a standard T85 model) + + logical :: check_fourier_imag = .false. + if true, checks to see if fields to be transformed to grid + domain have zero imaginary part to their zonally symmetric + modes; useful for debugging + + logical :: south_to_north = .true. + true => grid runs from south to north + false => grid runs from north to south + + logical :: triangular_trunc = .true. + true => shape of truncation is triangular + false => shape of truncation is rhomboidal + + real :: robert_coeff = 0.04 + x(current) => (1-2r)*x(current) + r*(x(future)+x(previous)) + where r = robert_coeff (non-dimensional) + + real :: longitude_origin = 0.0 + longitude of first longitude, in degrees + (if you want the westgern boundary of first grid boc to be at + 0.0, set longitude_origin = 0.5*360./float(num_lon)) + + integer :: damping_option = 'resolution_dependent' + integer :: damping_order = 4 + real :: damping_coeff = 1.e-04 + + damping = nu*(del^2)^n where n = damping order + damping_option = 'resolution_dependent' or 'resolution_independent' + = 'resolution_dependent' => nu is set so that the damping rate for the + mode (m=0,n=num_spherical-1) equals damping_coeff (in 1/s) + For triangular truncation, damping_coeff is then the + rate of damping of the highest retained mode + + = 'resolution_independent' => nu = damping_coef + + + real :: zeta_0 = 8.e-05 + integer :: m_0 = 4 + real :: eddy_width = 15.0 + real :: eddy_lat = 45.0 + + eddy component of the initial condition is sinusoidal with + wavenumber m_0 and with a gaussian distribution of + vorticity in latitude, centered at eddy_lat with half-width + eddy_width + + zeta_0 ( 1/s) + eddy_width and eddy_lat (degrees) + + logical :: spec_tracer = .true. + logical :: grid_tracer = .true. + spec_tracer = true => a passive tracer is carried that is advected + spectrally, with the same algorithm as the vorticity + grid_tracer = ture => a passive tracer is carried that is advected + on the spectral transform grid by a finite-volume algorithm + (see barotropic.ps ) + Both tracers can be carried simultaeneously + +The vorticity and the tracers are initialized within subroutine + barotropic_dynamics_init + + real, dimension(2) :: valid_range_v = -1000., 1000. + A valid range for meridional wind. Model terminates if meridional wind + goes outside the valid range. Allows model to terminate gracefully when, + for example, the model becomes numerically unstable. + ++ + + +
+ERROR MESSAGES
+ ++ + "Dynamics has not been initialized" + -- barotropic_dynamics_init must be called before any other + routines in the module are called + + "restart does not exist" + -- Time is not equal to Time_init at initalization, but the file + 'INPUT/barotropic_dynamics.res' does not exit + + ++ + + +
+ + diff --git a/src/atmos_spectral_barotropic/barotropic_physics.F90 b/src/atmos_spectral_barotropic/barotropic_physics.F90 new file mode 100644 index 000000000..8590bacce --- /dev/null +++ b/src/atmos_spectral_barotropic/barotropic_physics.F90 @@ -0,0 +1,173 @@ +module barotropic_physics_mod + +!----------------------------------------------------------------------- +! GNU General Public License +! +! This program is free software; you can redistribute it and/or modify it and +! are expected to follow the terms of the GNU General Public License +! as published by the Free Software Foundation; either version 2 of +! the License, or (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, but WITHOUT +! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +! License for more details. +! +! For the full text of the GNU General Public License, +! write to: Free Software Foundation, Inc., +! 675 Mass Ave, Cambridge, MA 02139, USA. +! or see: http://www.gnu.org/licenses/gpl.html +!----------------------------------------------------------------------- + +use fms_mod, only: open_namelist_file, & + open_restart_file, & + file_exist, & + check_nml_error, & + error_mesg, & + FATAL, WARNING, & + write_version_number, & + mpp_pe, & + mpp_root_pe, & + fms_init, fms_end, & + read_data, & + write_data, & + set_domain, & + close_file, & + stdlog + +use transforms_mod, only: get_sin_lat, get_cos_lat, & + get_deg_lon, get_deg_lat, & + get_wts_lat, & + get_grid_domain, get_spec_domain, & + grid_domain + +use time_manager_mod, only: time_type + +!======================================================================== +implicit none +private +!======================================================================== + +public :: barotropic_physics_init, & + barotropic_physics, & + barotropic_physics_end, & + phys_type + +! version information +!======================================================================== +character(len=128) :: version = '$Id: barotropic_physics.F90,v 10.0 2003/10/24 22:00:58 fms Exp $' +character(len=128) :: tagname = '$Name: siena_201207 $' +!======================================================================== + +type phys_type + real, pointer, dimension(:,:) :: empty=>NULL() +end type + +logical :: module_is_initialized = .false. + +integer :: is, ie, js, je + + +integer :: pe +logical :: root + +real, allocatable, dimension(:) :: rad_lat, & + deg_lat, & + sin_lat, & + cos_lat, & + wts_lat + +! namelist +!======================================================================== + +logical :: empty + +namelist /barotropic_physics_nml/ empty +!======================================================================== + +contains + +!======================================================================== + +subroutine barotropic_physics_init(Phys) + +type(phys_type), intent(inout) :: Phys + +integer :: j, unit, ierr, io + +call write_version_number (version, tagname) + +pe = mpp_pe() +root = (pe == mpp_root_pe()) + +! read the namelist + +if (file_exist('input.nml')) then + unit = open_namelist_file () + ierr=1 + do while (ierr /= 0) + read (unit, nml=barotropic_physics_nml, iostat=io, end=10) + ierr = check_nml_error (io, 'barotropic_physics_nml') + enddo + 10 call close_file (unit) +endif + +call get_grid_domain(is,ie,js,je) + +allocate ( rad_lat (js:je) ) +allocate ( deg_lat (js:je) ) +allocate ( sin_lat (js:je) ) +allocate ( cos_lat (js:je) ) +allocate ( wts_lat (js:je) ) + +call get_wts_lat(wts_lat) +call get_deg_lat(deg_lat) +rad_lat = deg_lat*atan(1.)/45. +sin_lat = sin(rad_lat) +cos_lat = cos(rad_lat) + +module_is_initialized = .true. + +return +end subroutine barotropic_physics_init + +!======================================================================= + +subroutine barotropic_physics(Time, dt_ug, dt_vg, ug, vg, & + delta_t, previous, current, Phys) + +real, intent(inout), dimension(is:ie, js:je) :: dt_ug, dt_vg +real, intent(in) , dimension(is:ie, js:je, 2) :: ug, vg + +real , intent(in) :: delta_t +integer, intent(in) :: previous, current + +type(time_type), intent(in) :: Time +type(phys_type), intent(inout) :: Phys + +if(.not.module_is_initialized) call error_mesg('barotropic_physics', & + 'barotropic_physics is not initialized', FATAL) + +! dt_ug = dt_ug +f(ug,vg) +! dt_vg = dt_vg +f(ug,vg) +! Phys%empty = + +return +end subroutine barotropic_physics + +!====================================================================== + +subroutine barotropic_physics_end(Phys) + +type(phys_type), intent(in) :: Phys + +if(.not.module_is_initialized) call error_mesg('barotropic_physics_end', & + 'barotropic_physics is not initialized', FATAL) + +module_is_initialized = .false. +return +end subroutine barotropic_physics_end + +!====================================================================== + +end module barotropic_physics_mod diff --git a/src/atmos_spectral_barotropic/barotropic_physics.html b/src/atmos_spectral_barotropic/barotropic_physics.html new file mode 100644 index 000000000..e391ca50f --- /dev/null +++ b/src/atmos_spectral_barotropic/barotropic_physics.html @@ -0,0 +1,165 @@ + +module barotropic_physics_mod + + +
+ + +module barotropic_physics_mod
+ + ++ Contact: Isaac Held + Reviewers: Peter Phillipps + ++ + + +
+OVERVIEW
+ ++ + A module that allows one to add processes that act in the grid domain + to the dynamics of the barotropic model on the sphere + ++ + + +
+DESCRIPTION
+ ++ + A module that allows one to add processes that act in the grid domain + to the dynamics of the barotropic model on the sphere. Currently, + does nothing! + ++ + + +
+OTHER MODULES USED
+ ++ + fms_mod + transforms_mod + time_manager_mod + ++ + + +
+PUBLIC INTERFACE
+ ++ + use barotropic_physics_mod [,only: barotropic_physics_init, + barotropic_physics, + barotropic_physics_end, + phys_type] + ++ + + +
+PUBLIC DATA
+ ++ ++ + +
+ + +type phys_type + real, pointer, dimension(:,:) :: empty +end type + + fields from physics module made available for diagnostics + +
+ + +
+PUBLIC ROUTINES
+ ++ +subroutine barotropic_physics_init +subroutine barotropic_physics +subroutine barotropic_physics_end +type(phys_type) + + + ++ + subroutine barotropic_physics_init(Phys) + + type(phys_type) , intent(inout) :: Phys + + + Initializes module + ++ +
+ + + + subroutine barotropic_physics (Time, dt_ug, dt_vg, ug, vg, & + delta_t, previous, current, Phys) + + real, intent(inout), dimension(:,:) :: dt_ug, dt_vg + + the u and v tendencies onto which tendencies due to + the grid-point physics are added (m/(s^2)) + + real, intent(in) , dimension(:,:, 2) :: ug, vg + the grid zonal and meridional velocities (m/s) + the third index is the time-index used in the leapfrog step + + real , intent(in) :: delta_t + time step (s) + + integer, intent(in) :: previous, current + = 1 or 2 + ug(:,:,previous) is the velocity at t-delta_t + ug(:,:,current ) is the velocity at t + + type(time_type), intent(in) :: Time + type(phys_type), intent(inout) :: Phys + + + + +
+ + + + subroutine barotropic_physics_end (Phys) + + type(phys_type), intent(inout) :: Phys + + + + +
+ + + diff --git a/src/atmos_spectral_barotropic/stirring.F90 b/src/atmos_spectral_barotropic/stirring.F90 new file mode 100644 index 000000000..7de10c3f1 --- /dev/null +++ b/src/atmos_spectral_barotropic/stirring.F90 @@ -0,0 +1,252 @@ +module stirring_mod + +!----------------------------------------------------------------------- +! GNU General Public License +! +! This program is free software; you can redistribute it and/or modify it and +! are expected to follow the terms of the GNU General Public License +! as published by the Free Software Foundation; either version 2 of +! the License, or (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, but WITHOUT +! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +! License for more details. +! +! For the full text of the GNU General Public License, +! write to: Free Software Foundation, Inc., +! 675 Mass Ave, Cambridge, MA 02139, USA. +! or see: http://www.gnu.org/licenses/gpl.html +!----------------------------------------------------------------------- + +! Stirring is computed as described in the following paper: + +! Vallis, Gerber, Kushner, Cash, 2003: A Mechanism and Simple Dynamical Model of the North Atlantic Oscillation and Annular Modes. +! J. Atmos. Sci., 61, 264-280. + +! Stirring is not part of barotropic_physics because barotropic_physics appears to be intended for +! operations that are done completely in grid space. Stirring is computed partly in spectral space. + +use constants_mod, only: pi + +use time_manager_mod, only: time_type + +use fms_mod, only: open_namelist_file, check_nml_error, close_file, write_version_number, & + stdlog, mpp_pe, mpp_root_pe, file_exist, read_data, write_data, error_mesg, FATAL + +use transforms_mod, only: get_spec_domain, get_grid_domain, trans_spherical_to_grid, trans_grid_to_spherical, & + grid_domain, get_lon_max, get_lat_max, get_deg_lon, get_deg_lat, get_grid_boundaries, & + get_num_fourier, get_num_spherical, spectral_domain + +use diag_manager_mod, only: diag_axis_init, register_static_field, register_diag_field, send_data + +implicit none +private + +integer :: ms,me,ns,ne,is,ie,js,je +integer :: id_str_amp, id_g_stir_sqr, id_stir +logical :: used +logical, allocatable, dimension(:,:) :: wave_mask ! wave_mask(m,n) = .true. if spherical wave (m,n) is to be excited +complex, allocatable, dimension(:,:) :: s_stir ! stirring. Saved from one time step to the next +real, allocatable, dimension(:,:) :: localize ! localizes the stirring +real, allocatable, dimension(:,:) :: g_stir_sqr ! time mean of g_stir**2 over entire integration +integer, allocatable, dimension(:) :: seed ! random number seed +real :: astir, bstir +integer :: num_steps, num_fourier, num_spherical, nseed + +logical :: module_is_initialized = .false. + +character(len=128) :: version = '$Id: stirring.F90,v 17.0 2009/07/21 03:00:25 fms Exp $' +character(len=128) :: tagname = '$Name: siena_201207 $' + +public :: stirring_init, stirring, stirring_end + +real :: decay_time=2*86400, amplitude=0.0, lat0=45., widthy=12. +logical :: do_localize=.true.!Default true to allow forcing to be localized in physical space. Set to false to have forcing everywhere. + +! Set B to a non-zero value for stirring that has zonal structure. +! The strength of the stirring at latitude=lat0 is: amplitude*(1.0 + B*exp(-.5*((lon-lon0)/widthx)**2)) +real :: lon0=180., B=0.0, widthx=45., C=1.0 ! widthx +integer :: n_total_forcing_max = 15 !total wavenumbers LESS THAN this number will be forced +integer :: n_total_forcing_min = 9 !total wavenumbers GREATER THAN this number will be forced +integer :: zonal_forcing_min = 3 !Zonal wavenumbers GREATER THAN this number will be forced, subject to total wavenumber constraints + +namelist / stirring_nml / decay_time, amplitude, lat0, lon0, widthy, widthx, B, do_localize, n_total_forcing_max, n_total_forcing_min, zonal_forcing_min + +contains + +!================================================================================================================================ +subroutine stirring_init(dt, Time, id_lon, id_lat, id_lonb, id_latb) +real, intent(in) :: dt +type(time_type), intent(in) :: Time +integer, intent(in) :: id_lon, id_lat, id_lonb, id_latb +real :: xx, kk, rad_to_deg +integer :: i,j,m,n,ierr,io,unit,lon_max,lat_max +real, allocatable, dimension(:) :: ampx, ampy, lon, lat, lonb, latb +real, allocatable, dimension(:,:) :: real_part, imag_part + +if(module_is_initialized) return + +call write_version_number (version, tagname) + +if (file_exist('input.nml')) then + unit = open_namelist_file () + ierr=1 + do while (ierr /= 0) + read (unit, nml=stirring_nml, iostat=io, end=10) + ierr = check_nml_error (io, 'stirring_nml') + enddo + 10 call close_file (unit) +endif +if(mpp_pe() == mpp_root_pe()) write(stdlog(), nml=stirring_nml) + +call get_lon_max(lon_max) +call get_lat_max(lat_max) + +allocate(lon (lon_max )) ; lon = 0.0 +allocate(lat (lat_max )) ; lat = 0.0 +allocate(lonb(lon_max+1)) ; lonb = 0.0 +allocate(latb(lat_max+1)) ; latb = 0.0 + +call get_deg_lon(lon) +call get_deg_lat(lat) + +module_is_initialized = .true. +if(amplitude == 0.0) return ! stirring does nothing more unless amplitude is non-zero + +call get_spec_domain(ms,me,ns,ne) +call get_grid_domain(is,ie,js,je) +call get_num_fourier(num_fourier) +call get_num_spherical(num_spherical) + +allocate(wave_mask(ms:me,ns:ne)); wave_mask = .false. +allocate(s_stir(ms:me,ns:ne)); s_stir = cmplx(0.0,0.0) +allocate(ampx(is:ie)); ampx = 0.0 +allocate(ampy(js:je)); ampy = 0.0 +allocate(localize(is:ie,js:je)); localize = 0.0 +allocate(g_stir_sqr(is:ie,js:je)); g_stir_sqr = 0.0 + +! wave_mask is .true. when (m+n > 9) .and. (m+n < 15) .and. (m > 3) +do m=(zonal_forcing_min+1),(n_total_forcing_max-1) + if(m >= ms .and. m <= me) then + do n=(n_total_forcing_min+1)-m,(n_total_forcing_max-1)-m + if(n >= ns .and. n <= ne) then + wave_mask(m,n) = .true. + endif + enddo + endif +enddo + +astir = sqrt(1.0 - exp(-2*dt/decay_time)) +bstir = exp(-dt/decay_time) + +do i=is,ie + xx = lon(i)-lon0 + ! Make sure xx falls in the range -180. to +180. + kk = nint(xx/360.) + xx = xx - 360.*kk + ampx(i) = (1 + B*exp(-.5*(xx/widthx)**2)) +enddo +do j=js,je + ampy(j) = exp(-.5*((lat(j)-lat0)/widthy)**2) +enddo +if (do_localize) then + do j=js,je + do i=is,ie + localize(i,j) = ampx(i)*ampy(j) + enddo + enddo +else + localize = 1.0 +endif + +deallocate(ampx, ampy) + +num_steps = 0 +id_g_stir_sqr = register_static_field('stirring_mod', 'stirring_sqr', (/id_lon,id_lat/), 'stirring sqrared', '1/sec^4') +id_str_amp = register_static_field('stirring_mod', 'stirring_amp', (/id_lon,id_lat/), 'amplitude of stirring', 'none') +id_stir = register_diag_field ('stirring_mod', 'stirring', (/id_lon,id_lat/), Time, 'stirring', '1/sec^2') +used = send_data(id_str_amp, amplitude*localize) + +call random_seed(size=nseed) +allocate(seed(nseed)) + +if(file_exist('INPUT/stirring.res.nc')) then + allocate(real_part(ms:me,ns:ne), imag_part(ms:me,ns:ne)) + call read_data('INPUT/stirring.res.nc', 'stir_real', real_part, spectral_domain) + call read_data('INPUT/stirring.res.nc', 'stir_imag', imag_part, spectral_domain) + do n=ns,ne + do m=ms,me + s_stir(m,n) = cmplx(real_part(m,n),imag_part(m,n)) + end do + end do + deallocate(real_part, imag_part) + call read_data('INPUT/stirring.res.nc', 'ran_nmbr_seed', seed, no_domain=.true.) + call random_seed(put=seed) +endif + +end subroutine stirring_init +!================================================================================================================================ +subroutine stirring(Time, dt_vors) +type(time_type), intent(in) :: Time +complex, dimension(ms:me,ns:ne), intent(inout) :: dt_vors +real, dimension(is:ie,js:je) :: g_stir +complex, dimension(ms:me,ns:ne) :: new_stirring +real, dimension(0:num_fourier,0:num_spherical,2) :: ran_nmbrs +integer :: i,j,m,n +real :: x,y + +if(.not.module_is_initialized) then + call error_mesg('stirring', 'stirring_init has not been called', FATAL) +end if + +if(amplitude == 0.0) return ! stirring does nothing unless amplitude is non-zero + +call random_number(ran_nmbrs) + +do n=ns,ne +do m=ms,me + if(wave_mask(m,n)) then + new_stirring(m,n) = amplitude*astir*cmplx(2*ran_nmbrs(m,n,1)-1, 2*ran_nmbrs(m,n,2)-1) + else + new_stirring(m,n) = cmplx(0.0,0.0) + endif +enddo +enddo +call trans_spherical_to_grid(new_stirring,g_stir) +g_stir = localize*g_stir +call trans_grid_to_spherical(g_stir,new_stirring) +if(ms == 0 .and. ns == 0) then + new_stirring(0,0)=cmplx(0.0,0.0) ! A non-zero global mean is introduced by the grid space computation, but we don't want it. +endif +s_stir = bstir*s_stir + new_stirring !This is equation A.6 in Vallis et al 2004 - DOI:10.1175/1520-0469(2004)061<0264:AMASDM>2.0.CO;2 + +dt_vors = dt_vors + s_stir +call trans_spherical_to_grid(s_stir,g_stir) +g_stir_sqr = g_stir_sqr + g_stir*g_stir +num_steps = num_steps + 1 +used = send_data(id_stir, g_stir, Time) + +end subroutine stirring +!================================================================================================================================ +subroutine stirring_end + +if(.not.module_is_initialized) return + +if(amplitude == 0.0) return ! stirring does nothing unless amplitude is non-zero + +g_stir_sqr = g_stir_sqr/num_steps +used = send_data(id_g_stir_sqr, g_stir_sqr) + +call write_data('RESTART/stirring.res.nc', 'stir_real', real(s_stir), spectral_domain) +call write_data('RESTART/stirring.res.nc', 'stir_imag', aimag(s_stir), spectral_domain) +call random_seed(get=seed) +call write_data('RESTART/stirring.res.nc', 'ran_nmbr_seed', seed, no_domain=.true.) + +deallocate(wave_mask, s_stir, localize, g_stir_sqr) +module_is_initialized = .false. + +end subroutine stirring_end +!================================================================================================================================ + +end module stirring_mod diff --git a/src/atmos_spectral_shallow/atmosphere.F90 b/src/atmos_spectral_shallow/atmosphere.F90 new file mode 100644 index 000000000..7336f9b72 --- /dev/null +++ b/src/atmos_spectral_shallow/atmosphere.F90 @@ -0,0 +1,281 @@ +Module atmosphere_mod + +!----------------------------------------------------------------------- +! GNU General Public License +! +! This program is free software; you can redistribute it and/or modify it and +! are expected to follow the terms of the GNU General Public License +! as published by the Free Software Foundation; either version 2 of +! the License, or (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, but WITHOUT +! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +! License for more details. +! +! For the full text of the GNU General Public License, +! write to: Free Software Foundation, Inc., +! 675 Mass Ave, Cambridge, MA 02139, USA. +! or see: http://www.gnu.org/licenses/gpl.html +!----------------------------------------------------------------------- + +!========================================================================= + +use fms_mod, only: open_namelist_file, & + open_restart_file, & + file_exist, & + check_nml_error, & + error_mesg, & + FATAL, WARNING, & + write_version_number, & + mpp_pe, & + mpp_root_pe, & + close_file, & + stdlog + +use mpp_mod, only: mpp_max + +use constants_mod, only: radius_earth => radius, & + omega_earth => omega + +use transforms_mod, only : get_deg_lon, & + get_deg_lat, & + get_grid_boundaries, & + get_grid_domain, & + get_spec_domain, & + area_weighted_global_mean, & + atmosphere_domain + +use time_manager_mod, only : time_type, & + set_time, & + get_time, & + interval_alarm, & + operator(+), & + operator(<), & + operator(==) + +use shallow_dynamics_mod, only : shallow_dynamics_init, & + shallow_dynamics, & + shallow_dynamics_end, & + dynamics_type + +use shallow_physics_mod, only : shallow_physics_init, & + shallow_physics, & + shallow_physics_end, & + phys_type + +use shallow_diagnostics_mod, only : shallow_diagnostics_init, & + shallow_diagnostics + +use stirring_mod, only: stirring_init + +!======================================================================== +implicit none +private +!======================================================================== + +! version information +!======================================================================== +character(len=128) :: version = '$Id: atmosphere.F90,v 14.0 2007/03/15 22:13:18 fms Exp $' +character(len=128) :: tagname = '$Name: siena_201207 $' +!======================================================================== + +public :: atmosphere_init, & + atmosphere, & + atmosphere_end, & + atmosphere_domain + +!======================================================================== + +integer, parameter :: num_time_levels = 2 + +integer :: unit, seconds, days +integer :: pe, npes +integer :: previous, current, future +logical :: root + +integer :: dt_integer +real :: dt_real +type(time_type) :: dt_time_type, Time_init, Time_step + +real :: delta_t ! = 2*dt_real for leapfrog step + +integer, dimension(2) :: axes + +type(phys_type), save :: Phys +type(dynamics_type), save :: Dyn + +integer :: is, ie, js, je, ms, me, ns, ne +integer :: num_lon, num_lat +integer, dimension(4) :: axis_id ! axes identifiers + +logical :: module_is_initialized =.false. + + +integer :: print_interval +! namelist +!======================================================================== +namelist /atmosphere_nml/ print_interval +!======================================================================== + +contains +!======================================================================= + +subroutine atmosphere_init(Time_init_in, Time, Time_step_in) + +type (time_type), intent(in) :: Time_init_in, Time, Time_step_in + +integer :: i, j, n, nn, ierr, io, unit, id_lon, id_lat, id_lonb, id_latb +integer :: nlon, nlat + +pe = mpp_pe() +root = (pe == mpp_root_pe()) + +Time_step = Time_step_in +call get_time(Time_step, seconds, days) +dt_integer = 86400*days + seconds +dt_real = float(dt_integer) +dt_time_type = Time_step +Time_init = Time_init_in + +! read the namelist + +if (file_exist('input.nml')) then + unit = open_namelist_file () + ierr=1 + do while (ierr /= 0) + read (unit, nml=atmosphere_nml, iostat=io, end=10) + ierr = check_nml_error (io, 'atmosphere_nml') + enddo + 10 call close_file (unit) +endif +call write_version_number(version, tagname) +if (root) write (stdlog(), nml=atmosphere_nml) + +call shallow_dynamics_init (Dyn, Time, Time_init, dt_real) + +call get_grid_domain(is,ie,js,je) +call get_spec_domain(ms,me,ns,ne) + +num_lon = Dyn%num_lon +num_lat = Dyn%num_lat + +nlon = ie+1-is ! size of grid on each processor +nlat = je+1-js + +call shallow_physics_init(Phys) +call shallow_diagnostics_init(Time, num_lon, num_lat, id_lon, id_lat, id_lonb, id_latb) +call stirring_init(dt_real, Time, id_lon, id_lat, id_lonb, id_latb) + +if(Time == Time_init) then + previous = 1 + current = 1 +else + previous = 1 + current = 2 +endif + +module_is_initialized = .true. + +return +end subroutine atmosphere_init + +!===================================================================== + +subroutine atmosphere(Time) + +type (time_type), intent(in) :: Time +integer :: day, second, dt + + +if(.not.module_is_initialized) then + call error_mesg('atmosphere', & + 'atmosphere_init has not been called', FATAL) +end if + +call get_time(Time_step, second, day) +dt = second + 86400*day + +Dyn%Tend%u = 0.0 +Dyn%Tend%v = 0.0 +Dyn%Tend%h = 0.0 +if(Dyn%grid_tracer) Dyn%Tend%tr = 0.0 +if(Dyn%spec_tracer) Dyn%Tend%trs = 0.0 + +if(Time == Time_init) then + delta_t = dt_real + future = 2 +else + delta_t = 2.0*dt_real + future = previous +endif + +call shallow_physics(Time, & + Dyn%Tend%u, Dyn%Tend%v, Dyn%Tend%h, & + Dyn%Grid%u, Dyn%Grid%v, Dyn%Grid%h, & + delta_t, previous, current, & + Phys) + +call shallow_dynamics(Time, Time_init, & + Dyn, previous, current, future, delta_t) + +previous = current +current = future + +call shallow_diagnostics (Time+Time_step, Dyn%Grid, Phys, current) + +call get_time(Time+Time_step, second, day) +if(mod(second+86400*day, print_interval) < dt) & + call global_diag(second, day, current) + +return +end subroutine atmosphere + +!======================================================================================= + +subroutine global_diag(second, day, current) + +integer, intent(in) :: second, day, current + +real :: enstrophy, div_squared, max_Froude +real, dimension(size(Dyn%Grid%u,1), size(Dyn%Grid%u,2)) :: speed + +enstrophy = & +area_weighted_global_mean(Dyn%grid%vor(:,:,current)*Dyn%grid%vor(:,:,current)) + +div_squared = & +area_weighted_global_mean(Dyn%grid%div(:,:,current)*Dyn%grid%div(:,:,current)) + +speed = Dyn%Grid%u(:,:,current)*Dyn%Grid%u(:,:,current) +& + Dyn%Grid%v(:,:,current)*Dyn%Grid%v(:,:,current) +max_Froude = maxval(speed/Dyn%Grid%h(:,:,current)) +call mpp_max(max_Froude) + +if(root) then + write(*,1000) day, second, enstrophy, div_squared, max_Froude +end if +1000 format(1x, 'day =',i6,2x,'second =', i6, & + 2x,'enstrophy = ',e13.6,3x,'div_squared = ',e13.6, 3x, & + 'max_Froude = ', e10.3) + +return +end subroutine global_diag + +!=============================================================================== +subroutine atmosphere_end + +if(.not.module_is_initialized) then + call error_mesg('atmosphere_end', & + 'atmosphere_init has not been called.', FATAL) +end if + +call shallow_physics_end (Phys) +call shallow_dynamics_end (Dyn, previous, current) + +module_is_initialized = .false. + +return +end subroutine atmosphere_end + +!======================================================================================= +end module atmosphere_mod diff --git a/src/atmos_spectral_shallow/atmosphere.html b/src/atmos_spectral_shallow/atmosphere.html new file mode 100644 index 000000000..13e269faf --- /dev/null +++ b/src/atmos_spectral_shallow/atmosphere.html @@ -0,0 +1,164 @@ + +module atmosphere_mod + + +
+ +module atmosphere_mod
+ + ++ Contact: Isaac Held + Reviewers: Peter Phillipps ++ + + +
+OVERVIEW
+ ++ A spectral transform model for the shallow water equations on the sphere ++ + + +
+DESCRIPTION
+ ++ Integrates the shallow water equations for hydrostatic flow in a thin layer + of homogeneous fluid on the sphere, using the spectral transform technique. + Also allows for the inclusion of a passive tracer advected by the + spectral advection algorithm as the vorticity, and a gridpoint tracer + advected with a finite volume algorithm on the transform grid. + The default experiment is forced by a "monsoonal" mass source, starting + from a state of rest. + + For a full description of the model and algorithms used, see shallow.ps + + The interfaces in this module are the generic intefaces required by the + main program that can be used to drive various idealized atmospheric + models within FMS. Model resolution and related parameters are set in + namelists within the modules shallow_xxx. ++ + + +
+OTHER MODULES USED
+ ++ fms_mod + constants_mod + transforms_mod + time_manager_mod + diag_manager_mod + shallow_dynamics_mod + shallow_physics_mod + shallow_diagnostics_mod ++ + + +
+PUBLIC INTERFACE
+ ++ use atmosphere_mod [,only: atmosphere_init, + atmosphere, + atmosphere_end] ++ + + +
+PUBLIC DATA
+ ++ There are no public data types ++ + + +
+PUBLIC ROUTINES
+ ++subroutine atmosphere_init. Initializes the model. +subroutine atmosphere. Integrates forward one time step +subroutine atmosphere_end. Terminates model, cleaning up memory and finalizing diagnostics. + + ++ + ++ subroutine atmosphere_init(Time_init, Time, Time_step) + + input: + + type(time_type) :: Time_init -- Initial model time + + type(time_type) :: Time -- Model time + + type(time_type) :: Time_step -- Time step + + When Time=Time_init, the first time step is a forward + step rather than leap frog because a cold start is assumed. + + The FMS main program that runs the solo atmospheric models + obtains Time_init from the diag_table and Time from its namelist. + ++
+ + + subroutine atmosphere(Time) + + input: + + type(time_type) :: Time -- Model time + + Integrates forward one time step + + +
+ + subroutine atmosphere_end + + No calling arguments. + + Terminates model, cleaning up memory and finalizing diagnostics + +
+NAMELIST
+ ++&atmosphere_nml + + print_interval, integer : time interval in seconds + between prints of global mean energy and enstrophy to standard output ++ + + +
+ERROR MESSAGES
+ ++ Fatal error message if subroutine atmosphere or atmosphere_end + is called prior to atmosphere_init. ++ + +
+ + diff --git a/src/atmos_spectral_shallow/shallow.pdf b/src/atmos_spectral_shallow/shallow.pdf new file mode 100644 index 000000000..3ae5dbd1a Binary files /dev/null and b/src/atmos_spectral_shallow/shallow.pdf differ diff --git a/src/atmos_spectral_shallow/shallow_diagnostics.F90 b/src/atmos_spectral_shallow/shallow_diagnostics.F90 new file mode 100644 index 000000000..3ea5dc0a8 --- /dev/null +++ b/src/atmos_spectral_shallow/shallow_diagnostics.F90 @@ -0,0 +1,259 @@ + +module shallow_diagnostics_mod + +!----------------------------------------------------------------------- +! GNU General Public License +! +! This program is free software; you can redistribute it and/or modify it and +! are expected to follow the terms of the GNU General Public License +! as published by the Free Software Foundation; either version 2 of +! the License, or (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, but WITHOUT +! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +! License for more details. +! +! For the full text of the GNU General Public License, +! write to: Free Software Foundation, Inc., +! 675 Mass Ave, Cambridge, MA 02139, USA. +! or see: http://www.gnu.org/licenses/gpl.html +!----------------------------------------------------------------------- + +use fms_mod, only: write_version_number + +use transforms_mod, only: get_grid_boundaries, & + get_deg_lon, & + get_deg_lat, & + get_grid_domain, & + get_spec_domain, & + grid_domain, & + area_weighted_global_mean + +use diag_manager_mod, only: diag_axis_init, & + register_diag_field, & + register_static_field, & + send_data + +use time_manager_mod, only: time_type, & + get_time + + +use shallow_physics_mod, only: phys_type +use shallow_dynamics_mod, only: grid_type + + +implicit none +private + +public :: shallow_diagnostics_init, & + shallow_diagnostics + +character(len=84), parameter :: version = '$Id: shallow_diagnostics.F90,v 10.0 2003/10/24 22:01:02 fms Exp $' +character(len=84), parameter :: tagname = '$Name: siena_201207 $' +character(len=8) :: axiset = 'shallow' +character(len=84) :: mod_name = 'shallow_diagnostics' + +logical :: module_is_initialized = .false. + +integer :: id_vor, id_stream, id_pv, id_u, id_v, id_div, id_h, id_trs, id_tr, id_d_geopot, id_u_sqd, id_v_sqd, id_h_sqd, id_u_sqd_mean, id_v_sqd_mean, id_h_sqd_mean, id_ekin, id_ekin_density, id_eq_geopot, id_e_kin_real_units, id_e_pot_real_units, id_e_tot_real_units, id_u_rms, id_vcomp_vor, id_ucomp_vcomp + +integer :: is, ie, js, je + +contains + +!----------------------------------------------------------------------------------------------------------------- +subroutine shallow_diagnostics_init(Time, lon_max, lat_max, id_lon, id_lat, id_lonb, id_latb) + +type(time_type), intent(in) :: Time +integer, intent(in) :: lon_max, lat_max +integer, intent(out):: id_lon, id_lat, id_lonb, id_latb + +real, dimension(lon_max ) :: lon +real, dimension(lon_max+1) :: lonb +real, dimension(lat_max ) :: lat +real, dimension(lat_max+1) :: latb + +integer, dimension(2) :: axis_2d + +integer :: log_unit +integer :: namelist_unit, ierr, io +real :: rad_to_deg +logical :: used + +call write_version_number(version, tagname) + +call get_grid_domain(is, ie, js, je) + +rad_to_deg = 45./atan(1.) +call get_grid_boundaries(lonb,latb,global=.true.) +call get_deg_lon(lon) +call get_deg_lat(lat) + +id_lonb=diag_axis_init('lonb', rad_to_deg*lonb, 'degrees_E', 'x', 'longitude edges', set_name=axiset, Domain2=grid_domain) +id_latb=diag_axis_init('latb', rad_to_deg*latb, 'degrees_N', 'y', 'latitude edges', set_name=axiset, Domain2=grid_domain) +id_lon =diag_axis_init('lon', lon, 'degrees_E', 'x', 'longitude', set_name=axiset, Domain2=grid_domain, edges=id_lonb) +id_lat =diag_axis_init('lat', lat, 'degrees_N', 'y', 'latitude', set_name=axiset, Domain2=grid_domain, edges=id_latb) + +axis_2d(1) = id_lon +axis_2d(2) = id_lat + +id_u = register_diag_field(mod_name, 'ucomp' , axis_2d, Time, 'u_wind' , 'm/s' ) +id_v = register_diag_field(mod_name, 'vcomp' , axis_2d, Time, 'v_wind' , 'm/s' ) +id_vor = register_diag_field(mod_name, 'vor' , axis_2d, Time, 'relative vorticity' , '1/s' ) +id_div = register_diag_field(mod_name, 'div' , axis_2d, Time, 'divergence' , '1/s' ) +id_h = register_diag_field(mod_name, 'h' , axis_2d, Time, 'geopotential' , 'm2/s2' ) +id_pv = register_diag_field(mod_name, 'pv_corrected' , axis_2d, Time, 'potential vorticity' , 's/m2' ) +id_stream = register_diag_field(mod_name, 'stream', axis_2d, Time, 'streamfunction' , 'm^2/s' ) +id_trs = register_diag_field(mod_name, 'trs' , axis_2d, Time, 'spectral tracer' , 'none' ) +id_tr = register_diag_field(mod_name, 'tr' , axis_2d, Time, 'grid tracer' , 'none' ) +id_d_geopot = register_diag_field(mod_name, 'deep_geopot', axis_2d, Time, 'deep_geopot' , 'm2/s2') + +id_u_sqd = register_diag_field(mod_name, 'ucomp_sqd' , axis_2d, Time, 'u_wind_sqd' , 'm^2/s^2' ) +id_v_sqd = register_diag_field(mod_name, 'vcomp_sqd' , axis_2d, Time, 'v_wind_sqd' , 'm^2/s^2' ) +id_h_sqd = register_diag_field(mod_name, 'h_sqd' , axis_2d, Time, 'geopotential_sqd' , 'm4/s4' ) + +id_u_sqd_mean = register_diag_field(mod_name, 'ucomp_sqd_mean' , Time, 'u_wind_sqd_mean' , 'm^2/s^2' ) +id_v_sqd_mean = register_diag_field(mod_name, 'vcomp_sqd_mean' , Time, 'v_wind_sqd_mean' , 'm^2/s^2' ) +id_h_sqd_mean = register_diag_field(mod_name, 'h_sqd_mean' , Time, 'geopotential_sqd_mean' , 'm4/s4' ) + +id_ekin = register_diag_field(mod_name, 'e_kin' , Time, 'kinetic_energy' , 'm^2/s^2' ) +id_ekin_density = register_diag_field(mod_name, 'e_kin_density' , Time, 'kinetic_energy_density' , 'm^3/s^2' ) + +id_eq_geopot = register_diag_field(mod_name, 'eq_geopot' , Time, 'equilibrium_geopotential' , 'm^2/s^2' ) +id_e_kin_real_units = register_diag_field(mod_name, 'e_kin_real_units' , Time, 'e_kin_real_units' , 'J/kg' ) +id_e_pot_real_units = register_diag_field(mod_name, 'e_pot_real_units' , Time, 'e_pot_real_units' , 'J/kg' ) +id_e_tot_real_units = register_diag_field(mod_name, 'e_tot_real_units' , Time, 'e_tot_real_units' , 'J/kg' ) + +id_u_rms = register_diag_field(mod_name, 'u_rms' , Time, 'r_rms' , 'm/s' ) + +id_vcomp_vor = register_diag_field(mod_name, 'vcomp_vor' , axis_2d, Time, 'vcomp * relative vorticity' , 'm/s^2' ) + +id_ucomp_vcomp = register_diag_field(mod_name, 'ucomp_vcomp' , axis_2d, Time, 'ucomp * vcomp' , 'm^2/s^2' ) + +module_is_initialized = .true. + +return +end subroutine shallow_diagnostics_init + +!-------------------------------------------------------------------------------------------- + +subroutine shallow_diagnostics(Time, Grid, Phys, time_index) + +type(time_type), intent(in) :: Time +type(phys_type), intent(in) :: Phys +type(grid_type), intent(in) :: Grid +integer, intent(in) :: time_index + +real :: e_kin_real_units, e_pot_real_units, e_tot_real_units, eq_geopot + +logical :: used + +if(id_u > 0) used = send_data(id_u , Grid%u (:,:, time_index) , time) +if(id_v > 0) used = send_data(id_v , Grid%v (:,:, time_index) , time) +if(id_vor > 0) used = send_data(id_vor , Grid%vor (:,:, time_index) , time) +if(id_div > 0) used = send_data(id_div , Grid%div (:,:, time_index) , time) +if(id_h > 0) used = send_data(id_h , Grid%h (:,:, time_index) , time) +if(id_pv > 0) used = send_data(id_pv , Grid%pv (:,:) , time) +if(id_stream > 0) used = send_data(id_stream , Grid%stream (:,:) , time) +if(id_tr > 0) used = send_data(id_tr , Grid%tr (:,:, time_index) , time) +if(id_trs > 0) used = send_data(id_trs , Grid%trs (:,:, time_index) , time) +if(id_d_geopot > 0) used = send_data(id_d_geopot, Grid%deep_geopot (:,:) , time) + +if (id_u_sqd > 0) then + used = send_data(id_u_sqd , Grid%u (:,:, time_index)**2 , time) +endif + +if (id_v_sqd > 0) then + used = send_data(id_v_sqd , Grid%v (:,:, time_index)**2 , time) +endif + +if (id_h_sqd > 0) then + used = send_data(id_h_sqd , Grid%h (:,:, time_index)**2 , time) +endif + +if (id_u_sqd_mean > 0) then + used = send_data(id_u_sqd_mean , area_weighted_global_mean(Grid%u (:,:, time_index)**2) , time) +endif + +if (id_v_sqd_mean > 0) then + used = send_data(id_v_sqd_mean , area_weighted_global_mean(Grid%v (:,:, time_index)**2) , time) +endif + +if (id_h_sqd_mean > 0) then + used = send_data(id_h_sqd_mean , area_weighted_global_mean(Grid%h (:,:, time_index)**2) , time) +endif + +if (id_ekin > 0) then + used = send_data(id_ekin , 0.5*(area_weighted_global_mean(Grid%u (:,:, time_index)**2) + area_weighted_global_mean(Grid%v (:,:, time_index)**2)) , time) +endif + +if (id_ekin_density > 0) then + used = send_data(id_ekin_density , 0.5*(area_weighted_global_mean(Grid%h (:,:, time_index)*(Grid%u (:,:, time_index)**2)) + area_weighted_global_mean(Grid%h (:,:, time_index)*(Grid%v (:,:, time_index)**2))) , time) +endif + +eq_geopot = 0. +e_kin_real_units = 0. +e_pot_real_units = 0. + +if (id_eq_geopot > 0) then + + eq_geopot = area_weighted_global_mean(Grid%h (:,:, time_index)) + used = send_data(id_eq_geopot , eq_geopot, time) + +endif + + +if (id_e_kin_real_units > 0) then + + if (eq_geopot == 0.) eq_geopot = area_weighted_global_mean(Grid%h (:,:, time_index)) + + e_kin_real_units = 0.5*(area_weighted_global_mean(Grid%h (:,:, time_index)*(Grid%u (:,:, time_index)**2)) + area_weighted_global_mean(Grid%h (:,:, time_index)*(Grid%v (:,:, time_index)**2))) / eq_geopot + + used = send_data(id_e_kin_real_units , e_kin_real_units, time) + +endif + +if (id_e_pot_real_units > 0) then + + if (eq_geopot == 0.) eq_geopot = area_weighted_global_mean(Grid%h (:,:, time_index)) + + e_pot_real_units = 0.5*(area_weighted_global_mean(Grid%h (:,:, time_index)**2.)) / eq_geopot + + used = send_data(id_e_pot_real_units , e_pot_real_units, time) + +endif + +if (id_e_tot_real_units > 0) then + + if (eq_geopot == 0.) eq_geopot = area_weighted_global_mean(Grid%h (:,:, time_index)) + + if (e_kin_real_units == 0.) then + e_kin_real_units = 0.5*(area_weighted_global_mean(Grid%h (:,:, time_index)*(Grid%u (:,:, time_index)**2)) + area_weighted_global_mean(Grid%h (:,:, time_index)*(Grid%v (:,:, time_index)**2))) / eq_geopot + endif + + if (e_pot_real_units == 0.) then + e_pot_real_units = 0.5*(area_weighted_global_mean(Grid%h (:,:, time_index)**2.)) / eq_geopot + endif + + e_tot_real_units = e_kin_real_units + e_pot_real_units + + used = send_data(id_e_tot_real_units , e_tot_real_units, time) + +endif + +if (id_u_rms > 0) then + + used = send_data(id_u_rms , (area_weighted_global_mean(Grid%u (:,:, time_index)**2) + area_weighted_global_mean(Grid%v (:,:, time_index)**2))**0.5, time) + +endif + + +if(id_vcomp_vor > 0) used = send_data(id_vcomp_vor , Grid%v (:,:, time_index) * Grid%vor (:,:, time_index) , time) +if(id_ucomp_vcomp > 0) used = send_data(id_ucomp_vcomp , Grid%u (:,:, time_index) * Grid%v (:,:, time_index) , time) + +return +end subroutine shallow_diagnostics +!-------------------------------------------------------------------------------------------- + +end module shallow_diagnostics_mod diff --git a/src/atmos_spectral_shallow/shallow_diagnostics.html b/src/atmos_spectral_shallow/shallow_diagnostics.html new file mode 100644 index 000000000..65db99f52 --- /dev/null +++ b/src/atmos_spectral_shallow/shallow_diagnostics.html @@ -0,0 +1,150 @@ + +module shallow_diagnostics_mod + + +
+ + +module shallow_diagnostics_mod
+ + ++ Contact: Isaac Held + Reviewers: Peter Phillipps + ++ + + +
+OVERVIEW
+ ++ + The diagnostics module for the model that solves the shallow water + equation on the sphere + ++ + + +
+DESCRIPTION
+ ++ + Using the diagnostics manager, creates output files for the shallow model. + Variables currently available for output are + zonal wind + meridional wind + relative vorticity + absolute vorticity + streamfunction + spectral tracer in grid domain + grid tracer + + Whether or not these fields are actually output, the location of the + output, the frequency of output, whether or not the output is averaged + in time or an instantaneous snapshot, is controlled by a + diag_table file utilized by the diagnostics manager module + + One can add other diagnostics by following the (somewhat convoluted) + pattern within the program + + ++ + + +
+OTHER MODULES USED
+ ++ + diag_manaager_mod + transforms_mod + time_manager_mod + shallow_dynamics_mod + shallow_physics_mod + ++ + + +
+PUBLIC INTERFACE
+ ++ + use shallow_diagnostics_mod [,only: shallow_diagnostics_init, + shallow_diagnostics] + ++ + + + +
+PUBLIC ROUTINES
+ ++ +subroutine shallow_diagnostics_init +subroutine shallow_diagnostics + + ++ + subroutine shallow_diagnostics_init(Time, num_lon, num_lat) + + type(time_type) , intent(in) :: Time + current time + integer, intent(in) :: num_lon, num_lat + num_lon = number of longitudes in global domain + num_lat = number of latitudes in global domain + + + Initializes module + ++ +
+ + + + subroutine shallow_diagnostics (Time, Grid, Phys, time_index) + + type(time_type), intent(in) :: Time + type(phys_type), intent(in) :: Phys + type(grid_type), intent(in) :: Grid + integer, intent(in) :: time_index + + phys_type is defined in shallow_physics_mod; ; + + grid_type is defined in shallow_dynamics_mod: + Grid contains all of the fields to be output + + many of the grid fields in grid_type are dimensioned (lon, lat, time_index) + where time_index = 1 or 2 -- the two time levels needed to update the + state of the model using a leapfrog step are toggled between (:,:,1) + and (:,:,2). The input time_index (which must equal either 1 or 2) + determines which of these two fields is output) + + (this is confusing -- the calling program needs to know what has + been placed in which slot -- it would be better to store this + information within the data type) + + + + +
+ + + diff --git a/src/atmos_spectral_shallow/shallow_dynamics.F90 b/src/atmos_spectral_shallow/shallow_dynamics.F90 new file mode 100644 index 000000000..14b7e89db --- /dev/null +++ b/src/atmos_spectral_shallow/shallow_dynamics.F90 @@ -0,0 +1,730 @@ +module shallow_dynamics_mod + +!----------------------------------------------------------------------- +! GNU General Public License +! +! This program is free software; you can redistribute it and/or modify it and +! are expected to follow the terms of the GNU General Public License +! as published by the Free Software Foundation; either version 2 of +! the License, or (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, but WITHOUT +! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +! License for more details. +! +! For the full text of the GNU General Public License, +! write to: Free Software Foundation, Inc., +! 675 Mass Ave, Cambridge, MA 02139, USA. +! or see: http://www.gnu.org/licenses/gpl.html +!----------------------------------------------------------------------- + +use fms_mod, only: open_namelist_file, & + open_restart_file, & + file_exist, & + check_nml_error, & + error_mesg, & + FATAL, & + write_version_number, & + mpp_pe, & + mpp_root_pe, & + read_data, & + write_data, & + set_domain, & + close_file, & + stdlog + +use time_manager_mod, only : time_type, & + get_time, & + operator(==), & + operator(-) + +use constants_mod, only : radius, omega, DEG_TO_RAD + +use transforms_mod, only: transforms_init, transforms_end, & + get_grid_boundaries, horizontal_advection, & + trans_spherical_to_grid, trans_grid_to_spherical, & + compute_laplacian, get_eigen_laplacian, & + get_sin_lat, get_cos_lat, & + get_deg_lon, get_deg_lat, & + get_grid_domain, get_spec_domain, & + spectral_domain, grid_domain, & + vor_div_from_uv_grid, uv_grid_from_vor_div, & + area_weighted_global_mean + +use spectral_damping_mod, only: spectral_damping_init, compute_spectral_damping + +use leapfrog_mod, only: leapfrog + +use fv_advection_mod, only : fv_advection_init, a_grid_horiz_advection + +use stirring_mod, only : stirring, stirring_end + +use interpolator_mod, only: interpolate_type,interpolator_init,CONSTANT,interpolator + +!====================================================================================== +implicit none +private +!====================================================================================== + +public :: shallow_dynamics_init, shallow_dynamics, shallow_dynamics_end, & + dynamics_type, grid_type, spectral_type, tendency_type + + +! version information +!=================================================================== +character(len=128) :: version = '$Id: shallow_dynamics.F90,v 10.0 2003/10/24 22:01:02 fms Exp $' +character(len=128) :: tagname = '$Name: siena_201207 $' +!=================================================================== + +type grid_type + real, pointer, dimension(:,:,:) :: u=>NULL(), v=>NULL(), vor=>NULL(), div=>NULL(), h=>NULL(), trs=>NULL(), tr=>NULL() + real, pointer, dimension(:,:) :: stream=>NULL(), pv=>NULL(), deep_geopot=>NULL() +end type +type spectral_type + complex, pointer, dimension(:,:,:) :: vor=>NULL(), div=>NULL(), h=>NULL(), trs=>NULL() +end type +type tendency_type + real, pointer, dimension(:,:) :: u=>NULL(), v=>NULL(), h=>NULL(), trs=>NULL(), tr=>NULL() +end type +type dynamics_type + type(grid_type) :: grid + type(spectral_type) :: spec + type(tendency_type) :: tend + integer :: num_lon, num_lat + logical :: grid_tracer, spec_tracer +end type + + + +integer, parameter :: num_time_levels = 2 + +integer :: is, ie, js, je, ms, me, ns, ne + +logical :: module_is_initialized = .false. + +real, allocatable, dimension(:) :: sin_lat, cos_lat, rad_lat, deg_lat, deg_lon, & + coriolis + +real, allocatable, dimension(:,:) :: eigen + +integer :: pe, npes + + +! namelist parameters with default values + +integer :: num_lon = 256 +integer :: num_lat = 128 +integer :: num_fourier = 85 +integer :: num_spherical = 86 +integer :: fourier_inc = 1 +integer :: cutoff_wn = 30 +! (these define a standard T85 model) + +logical :: check_fourier_imag = .false. +logical :: south_to_north = .true. +logical :: triang_trunc = .true. + +real :: robert_coeff = 0.04 +real :: robert_coeff_tracer = 0.04 +real :: longitude_origin = 0.0 +real :: raw_filter_coeff = 1.0 + +character(len=64) :: damping_option = 'resolution_dependent' +integer :: damping_order = 4 +real :: damping_coeff = 1.e-04 +real :: h_0 = 3.e04 + +real :: u_deep_mag = 0. +real :: n_merid_deep_flow = 3. +real :: u_upper_mag_init = 0. + +logical :: spec_tracer = .true. +logical :: grid_tracer = .true. + +!Options for injecting an initial vortex pair +real :: lon_centre_init_cyc = 0. +real :: lat_centre_init_cyc = 60. +real :: lon_centre_init_acyc = 180. +real :: lat_centre_init_acyc = 60. +real :: init_vortex_radius_deg = 5. +real :: init_vortex_vor_f = 0.5 +real :: init_vortex_h_h_0 = 0.1 +logical :: add_initial_vortex_pair = .false. +logical :: add_initial_vortex_as_height = .true. + +logical :: initial_condition_from_input_file=.false. +character(len=64) :: init_cond_file = 'init_cond_h_vor_div' +character(len=64) :: input_file_div_name = 'div' +character(len=64) :: input_file_height_name = 'height' +character(len=64) :: input_file_vor_name = 'vor' + +real, dimension(2) :: valid_range_v = (/-1.e3,1.e3/) + +type(interpolate_type),save :: init_cond_interp + +namelist /shallow_dynamics_nml/ check_fourier_imag, & + south_to_north, triang_trunc, & + num_lon, num_lat, num_fourier, & + num_spherical, fourier_inc, & + longitude_origin, damping_option, & + damping_order, damping_coeff, & + robert_coeff, robert_coeff_tracer, & + h_0, spec_tracer, grid_tracer, & + valid_range_v, cutoff_wn, & + raw_filter_coeff, & + u_deep_mag, n_merid_deep_flow, & + u_upper_mag_init, & + lon_centre_init_cyc, & + lat_centre_init_cyc, & + lon_centre_init_acyc, & + lat_centre_init_acyc, & + init_vortex_radius_deg, & + init_vortex_vor_f, & + init_vortex_h_h_0, & + add_initial_vortex_pair, & + add_initial_vortex_as_height, & + initial_condition_from_input_file, & + init_cond_file, & + input_file_div_name, & + input_file_height_name, & + input_file_vor_name + + +contains + +!======================================================================================= + +subroutine shallow_dynamics_init (Dyn, Time, Time_init, dt_real) + +type(dynamics_type), intent(inout) :: Dyn +type(time_type) , intent(in) :: Time, Time_init +real , intent(in) :: dt_real + +integer :: i, j + +real, allocatable, dimension(:) :: glon_bnd, glat_bnd +real, allocatable, dimension(:,:) :: rad_lonb_2d, rad_latb_2d +real :: xx, yy, dd, deep_geopot_global_mean, radius_loc_cyc, radius_loc_acyc + +integer :: ierr, io, unit, id_lon, id_lat, id_lonb, id_latb +logical :: root + +! < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > + +call write_version_number (version, tagname) + +pe = mpp_pe() +root = (pe == mpp_root_pe()) + +if (file_exist('input.nml')) then + unit = open_namelist_file () + ierr=1 + do while (ierr /= 0) + read (unit, nml=shallow_dynamics_nml, iostat=io, end=10) + ierr = check_nml_error (io, 'shallow_dynamics_nml') + enddo + 10 call close_file (unit) +endif + +if (root) write (stdlog(), nml=shallow_dynamics_nml) + +call transforms_init(radius, num_lat, num_lon, num_fourier, fourier_inc, num_spherical, & + south_to_north=south_to_north, & + triang_trunc=triang_trunc, & + longitude_origin=longitude_origin ) + +call get_grid_domain(is,ie,js,je) +call get_spec_domain(ms,me,ns,ne) + +Dyn%num_lon = num_lon +Dyn%num_lat = num_lat +Dyn%spec_tracer = spec_tracer +Dyn%grid_tracer = grid_tracer + +allocate (sin_lat (js:je)) +allocate (cos_lat (js:je)) +allocate (deg_lat (js:je)) +allocate (deg_lon (is:ie)) +allocate (coriolis (js:je)) + +call get_deg_lon (deg_lon) +call get_deg_lat (deg_lat) +call get_sin_lat (sin_lat) +call get_cos_lat (cos_lat) + +allocate (glon_bnd (num_lon + 1)) +allocate (glat_bnd (num_lat + 1)) +call get_grid_boundaries (glon_bnd, glat_bnd, global=.true.) +allocate (rad_lonb_2d(is:ie+1, js:je+1)) +allocate (rad_latb_2d(is:ie+1, js:je+1)) + +do i = is,ie+1 + rad_lonb_2d(i,:) = glon_bnd(i) +enddo + +do j = js,je+1 + rad_latb_2d(:,j) = glat_bnd(j) +enddo + +coriolis = 2*omega*sin_lat + +call spectral_damping_init(damping_coeff, damping_order, damping_option, cutoff_wn, num_fourier, num_spherical, 1, 0., 0., 0.) + +allocate(eigen(ms:me,ns:ne)) +call get_eigen_laplacian(eigen) + +allocate (Dyn%spec%vor (ms:me, ns:ne, num_time_levels)) +allocate (Dyn%spec%div (ms:me, ns:ne, num_time_levels)) +allocate (Dyn%spec%h (ms:me, ns:ne, num_time_levels)) + +allocate (Dyn%grid%u (is:ie, js:je, num_time_levels)) +allocate (Dyn%grid%v (is:ie, js:je, num_time_levels)) +allocate (Dyn%grid%vor (is:ie, js:je, num_time_levels)) +allocate (Dyn%grid%div (is:ie, js:je, num_time_levels)) +allocate (Dyn%grid%h (is:ie, js:je, num_time_levels)) + +allocate (Dyn%tend%u (is:ie, js:je)) +allocate (Dyn%tend%v (is:ie, js:je)) +allocate (Dyn%tend%h (is:ie, js:je)) +allocate (Dyn%grid%stream (is:ie, js:je)) +allocate (Dyn%grid%pv (is:ie, js:je)) +allocate (Dyn%grid%deep_geopot(is:ie, js:je)) + + +call fv_advection_init(num_lon, num_lat, glat_bnd, 360./float(fourier_inc)) +if(Dyn%grid_tracer) then + allocate(Dyn%Grid%tr (is:ie, js:je, num_time_levels)) + allocate(Dyn%Tend%tr (is:ie, js:je)) +endif + +if(Dyn%spec_tracer) then + allocate(Dyn%Grid%trs (is:ie, js:je, num_time_levels)) + allocate(Dyn%Tend%trs (is:ie, js:je)) + allocate(Dyn%Spec%trs (ms:me, ns:ne, num_time_levels)) +endif + +if( initial_condition_from_input_file ) then + call interpolator_init( init_cond_interp, trim(init_cond_file)//'.nc', rad_lonb_2d, rad_latb_2d, data_out_of_bounds=(/CONSTANT/) ) +endif + + +do i = is, ie + Dyn%grid%deep_geopot(i, js:je) = -2.*omega * u_deep_mag * radius * (1./(1.-n_merid_deep_flow**2.))*(-cos(n_merid_deep_flow*DEG_TO_RAD*deg_lat(js:je))*cos(DEG_TO_RAD*deg_lat(js:je)) - n_merid_deep_flow * (sin(n_merid_deep_flow*DEG_TO_RAD*deg_lat(js:je))*sin(DEG_TO_RAD*deg_lat(js:je))-sin(n_merid_deep_flow*(2.*atan(1.))))) +enddo + +deep_geopot_global_mean = area_weighted_global_mean(Dyn%grid%deep_geopot(:,:)) +Dyn%grid%deep_geopot(:,:) = Dyn%grid%deep_geopot(:,:)-deep_geopot_global_mean + +if(Time == Time_init) then + + if (initial_condition_from_input_file) then + + call interpolator( init_cond_interp, Dyn%Grid%div(:,:,1), input_file_div_name ) + call interpolator( init_cond_interp, Dyn%Grid%h(:,:,1), input_file_height_name ) + call interpolator( init_cond_interp, Dyn%Grid%vor(:,:,1), input_file_vor_name ) + + Dyn%Grid%h(:,:,1) = Dyn%Grid%h(:,:,1)+h_0 !want to make sure that we keep h_0 consistent, so make sure mean of h input is zero, and add h_0 on afterwards... + + else + Dyn%Grid%div(:,:,1) = 0.0 + Dyn%Grid%h (:,:,1) = h_0 - Dyn%grid%deep_geopot(:,:) + + do i = is, ie + Dyn%Grid%vor(i,js:je,1) = -((u_upper_mag_init * n_merid_deep_flow)/radius) * sin(DEG_to_RAD * deg_lat(js:je)) + + if (add_initial_vortex_pair) then + + do j=js, je + + radius_loc_cyc = ((min((deg_lon(i)-lon_centre_init_cyc)**2., (deg_lon(i)-lon_centre_init_cyc-360.)**2.)+(deg_lat(j)-lat_centre_init_cyc)**2.)**0.5)/init_vortex_radius_deg + radius_loc_acyc = ((min((deg_lon(i)-lon_centre_init_acyc)**2., (deg_lon(i)-lon_centre_init_acyc-360.)**2.)+(deg_lat(j)-lat_centre_init_acyc)**2.)**0.5)/init_vortex_radius_deg + + + if(radius_loc_cyc.le.1.0 .and. radius_loc_acyc.le.1.0) then + call error_mesg('shallow_dynamics','Cannot initialise cyclone and anticyclone in same grid box ', FATAL) + endif + + if(add_initial_vortex_as_height) then + if (radius_loc_cyc.le.2.0) then + Dyn%Grid%h(i,j,1) = Dyn%Grid%h(i,j,1) + init_vortex_h_h_0 * -h_0 * exp(-radius_loc_cyc**2.) + elseif (radius_loc_acyc.le.2.0) then + Dyn%Grid%h(i,j,1) = Dyn%Grid%h(i,j,1) + init_vortex_h_h_0 * h_0 * exp(-radius_loc_acyc**2.) + endif + else + if (radius_loc_cyc.le.1.0) then + Dyn%Grid%vor(i,j,1) = init_vortex_vor_f * 2.*omega + elseif (radius_loc_acyc.le.1.0) then + Dyn%Grid%vor(i,j,1) = init_vortex_vor_f * -2.*omega + endif + + endif + + enddo + + + endif !add_initial_vortex_pair + enddo + + endif ! initial_condition_from_input_file + + call trans_grid_to_spherical(Dyn%Grid%vor(:,:,1), Dyn%Spec%vor(:,:,1)) + call trans_grid_to_spherical(Dyn%Grid%div(:,:,1), Dyn%Spec%div(:,:,1)) + call trans_grid_to_spherical(Dyn%Grid%h (:,:,1), Dyn%Spec%h (:,:,1)) + + call uv_grid_from_vor_div (Dyn%Spec%vor(:,:,1), Dyn%Spec%div(:,:,1), & + Dyn%Grid%u (:,:,1), Dyn%Grid%v (:,:,1)) + + if(Dyn%grid_tracer) then + Dyn%Grid%tr = 0.0 + do j = js, je + if(deg_lat(j) > 10.0 .and. deg_lat(j) < 20.0) Dyn%Grid%tr(:,j,1) = 1.0 + if(deg_lat(j) > 70.0 ) Dyn%Grid%tr(:,j,1) = -1.0 + end do + endif + + if(Dyn%spec_tracer) then + Dyn%Grid%trs = 0.0 + do j = js, je + if(deg_lat(j) > 10.0 .and. deg_lat(j) < 20.0) Dyn%Grid%trs(:,j,1) = 1.0 + if(deg_lat(j) > 70.0 ) Dyn%Grid%trs(:,j,1) = -1.0 + end do + call trans_grid_to_spherical(Dyn%Grid%trs(:,:,1), Dyn%Spec%trs(:,:,1)) + endif + +else + + call read_restart(Dyn) + +endif + +module_is_initialized = .true. + +return +end subroutine shallow_dynamics_init + +!======================================================================================== + +subroutine shallow_dynamics(Time, Time_init, Dyn, previous, current, future, delta_t) + +type(time_type) , intent(in) :: Time, Time_init +type(dynamics_type), intent(inout) :: Dyn +integer, intent(in ) :: previous, current, future +real, intent(in ) :: delta_t + +! < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > + +complex, dimension(ms:me, ns:ne) :: dt_vors, dt_divs, dt_hs, stream, bs, work +real, dimension(is:ie, js:je) :: vorg, bg, h_future, h_dt, dt_vorg +integer :: j + +! < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > + +if(.not.module_is_initialized) then + call error_mesg('shallow_dynamics','dynamics has not been initialized ', FATAL) +endif + + +do j = js,je + vorg(:,j) = Dyn%Grid%vor(:,j,current) + coriolis(j) +end do +Dyn%Tend%u = Dyn%Tend%u + vorg*Dyn%Grid%v(:,:,current) +Dyn%Tend%v = Dyn%Tend%v - vorg*Dyn%Grid%u(:,:,current) + +call vor_div_from_uv_grid (Dyn%Tend%u, Dyn%Tend%v, dt_vors, dt_divs) + +call horizontal_advection (Dyn%Spec%h(:,:,current), & + Dyn%Grid%u(:,:,current), Dyn%Grid%v(:,:,current), Dyn%Tend%h) + +Dyn%Tend%h = Dyn%Tend%h - Dyn%Grid%h(:,:,current)*Dyn%Grid%div(:,:,current) + +call trans_grid_to_spherical (Dyn%Tend%h, dt_hs) + +bg = (Dyn%Grid%h(:,:,current) + Dyn%grid%deep_geopot(:,:) + & + 0.5*(Dyn%Grid%u(:,:,current)**2 + Dyn%Grid%v(:,:,current)**2)) + +call trans_grid_to_spherical(bg, bs) +dt_divs = dt_divs - compute_laplacian(bs) + +call implicit_correction (dt_divs, dt_hs, Dyn%Spec%div, Dyn%Spec%h, & + delta_t, previous, current) + +call compute_spectral_damping(Dyn%Spec%vor(:,:,previous), dt_vors, delta_t) +call compute_spectral_damping(Dyn%Spec%div(:,:,previous), dt_divs, delta_t) +call compute_spectral_damping(Dyn%Spec%h (:,:,previous), dt_hs , delta_t) + +call stirring(Time, dt_vors) + +call leapfrog(Dyn%Spec%vor , dt_vors , previous, current, future, delta_t, robert_coeff, raw_filter_coeff) +call leapfrog(Dyn%Spec%div , dt_divs , previous, current, future, delta_t, robert_coeff, raw_filter_coeff) +call leapfrog(Dyn%Spec%h , dt_hs , previous, current, future, delta_t, robert_coeff, raw_filter_coeff) + +call trans_spherical_to_grid(Dyn%Spec%vor(:,:,future), Dyn%Grid%vor(:,:,future)) +call trans_spherical_to_grid(Dyn%Spec%div(:,:,future), Dyn%Grid%div(:,:,future)) + + +call uv_grid_from_vor_div (Dyn%Spec%vor (:,:,future), Dyn%Spec%div(:,:,future), & + Dyn%Grid%u (:,:,future), Dyn%Grid%v (:,:,future)) + +call trans_spherical_to_grid (Dyn%Spec%h (:,:,future), Dyn%Grid%h(:,:,future)) + +if(minval(Dyn%Grid%v) < valid_range_v(1) .or. maxval(Dyn%Grid%v) > valid_range_v(2)) then + call error_mesg('shallow_dynamics','meridional wind out of valid range', FATAL) +endif + +if(Dyn%spec_tracer) call update_spec_tracer(Dyn%Spec%trs, Dyn%Grid%trs, Dyn%Tend%trs, & + Dyn%Grid%u, Dyn%Grid%v, previous, current, future, delta_t) + +if(Dyn%grid_tracer) call update_grid_tracer(Dyn%Grid%tr, Dyn%Tend%tr, & + Dyn%Grid%u, Dyn%Grid%v, previous, current, future, delta_t) + + +! for diagnostics + +stream = compute_laplacian(Dyn%Spec%vor(:,:,current), -1) ! for diagnostic purposes +call trans_spherical_to_grid(stream, Dyn%grid%stream) + +Dyn%Grid%pv = vorg/(Dyn%Grid%h(:,:,current)) + +return +end subroutine shallow_dynamics +!================================================================================ + +subroutine implicit_correction(dt_divs, dt_hs, divs, hs, delta_t, previous, current) + +complex, intent(inout), dimension(ms:,ns:) :: dt_divs, dt_hs +complex, intent(in), dimension(ms:,ns:,:) :: divs, hs +real , intent(in) :: delta_t +integer, intent(in) :: previous, current + +real :: xi, mu, mu2 + +xi = 0.5 ! centered implicit (for backwards implicit, set xi = 1.0) + +mu = xi*delta_t +mu2 = mu*mu + +dt_hs = dt_hs + h_0*(divs(:,:,current) - divs(:,:,previous)) +dt_divs = dt_divs - eigen*(hs(:,:,current) - hs(:,:,previous)) + +dt_divs = (dt_divs + mu*eigen*dt_hs)/(1.0 + mu2*eigen*h_0) +dt_hs = dt_hs - mu*h_0*dt_divs + +return +end subroutine implicit_correction + +!=================================================================================== + +subroutine update_spec_tracer(tr_spec, tr_grid, dt_tr, ug, vg, & + previous, current, future, delta_t) + +complex, intent(inout), dimension(ms:me, ns:ne, num_time_levels) :: tr_spec +real , intent(inout), dimension(is:ie, js:je, num_time_levels) :: tr_grid +real , intent(inout), dimension(is:ie, js:je ) :: dt_tr +real , intent(in ), dimension(is:ie, js:je, num_time_levels) :: ug, vg +real , intent(in ) :: delta_t +integer, intent(in ) :: previous, current, future + +complex, dimension(ms:me, ns:ne) :: dt_trs + +call horizontal_advection (tr_spec(:,:,current), ug(:,:,current), vg(:,:,current), dt_tr) +call trans_grid_to_spherical (dt_tr, dt_trs) +call compute_spectral_damping (tr_spec(:,:,previous), dt_trs, delta_t) +call leapfrog (tr_spec, dt_trs, previous, current, future, delta_t, robert_coeff, raw_filter_coeff) +call trans_spherical_to_grid (tr_spec(:,:,future), tr_grid(:,:,future)) + +return +end subroutine update_spec_tracer +!========================================================================== + +subroutine update_grid_tracer(tr_grid, dt_tr_grid, ug, vg, & + previous, current, future, delta_t) + +real , intent(inout), dimension(is:ie, js:je, num_time_levels) :: tr_grid +real , intent(inout), dimension(is:ie, js:je ) :: dt_tr_grid +real , intent(in ), dimension(is:ie, js:je, num_time_levels) :: ug, vg + +real , intent(in ) :: delta_t +integer, intent(in ) :: previous, current, future + +real, dimension(is:ie,js:je) :: tr_current, tr_future + +tr_future = tr_grid(:,:,previous) + delta_t*dt_tr_grid +dt_tr_grid = 0.0 +call a_grid_horiz_advection (ug(:,:,current), vg(:,:,current), tr_future, delta_t, dt_tr_grid) +tr_future = tr_future + delta_t*dt_tr_grid +tr_current = tr_grid(:,:,current) + & + robert_coeff_tracer*(tr_grid(:,:,previous) + tr_future - 2.0*tr_grid(:,:,current)) +tr_grid(:,:,current) = tr_current +tr_grid(:,:,future) = tr_future + +return +end subroutine update_grid_tracer + +!========================================================================== + +subroutine read_restart(Dyn) + +type(dynamics_type), intent(inout) :: Dyn + +integer :: unit, m, n, nt +real, dimension(ms:me, ns:ne) :: real_part, imag_part + +if(file_exist('INPUT/shallow_dynamics.res.nc')) then + do nt = 1, 2 + call read_data('INPUT/shallow_dynamics.res.nc', 'vors_real', real_part, spectral_domain, timelevel=nt) + call read_data('INPUT/shallow_dynamics.res.nc', 'vors_imag', imag_part, spectral_domain, timelevel=nt) + do n=ns,ne + do m=ms,me + Dyn%Spec%vor(m,n,nt) = cmplx(real_part(m,n),imag_part(m,n)) + end do + end do + call read_data('INPUT/shallow_dynamics.res.nc', 'divs_real', real_part, spectral_domain, timelevel=nt) + call read_data('INPUT/shallow_dynamics.res.nc', 'divs_imag', imag_part, spectral_domain, timelevel=nt) + do n=ns,ne + do m=ms,me + Dyn%Spec%div(m,n,nt) = cmplx(real_part(m,n),imag_part(m,n)) + end do + end do + call read_data('INPUT/shallow_dynamics.res.nc', 'hs_real', real_part, spectral_domain, timelevel=nt) + call read_data('INPUT/shallow_dynamics.res.nc', 'hs_imag', imag_part, spectral_domain, timelevel=nt) + do n=ns,ne + do m=ms,me + Dyn%Spec%h(m,n,nt) = cmplx(real_part(m,n),imag_part(m,n)) + end do + end do + if(Dyn%spec_tracer) then + call read_data('INPUT/shallow_dynamics.res.nc', 'trs_real', real_part, spectral_domain, timelevel=nt) + call read_data('INPUT/shallow_dynamics.res.nc', 'trs_imag', imag_part, spectral_domain, timelevel=nt) + do n=ns,ne + do m=ms,me + Dyn%Spec%trs(m,n,nt) = cmplx(real_part(m,n),imag_part(m,n)) + end do + end do + endif + call read_data('INPUT/shallow_dynamics.res.nc', 'u', Dyn%Grid%u (:,:,nt), grid_domain, timelevel=nt) + call read_data('INPUT/shallow_dynamics.res.nc', 'v', Dyn%Grid%v (:,:,nt), grid_domain, timelevel=nt) + call read_data('INPUT/shallow_dynamics.res.nc', 'vor', Dyn%Grid%vor(:,:,nt), grid_domain, timelevel=nt) + call read_data('INPUT/shallow_dynamics.res.nc', 'div', Dyn%Grid%div(:,:,nt), grid_domain, timelevel=nt) + call read_data('INPUT/shallow_dynamics.res.nc', 'h', Dyn%Grid%h (:,:,nt), grid_domain, timelevel=nt) + if(Dyn%spec_tracer) then + call read_data('INPUT/shallow_dynamics.res.nc', 'trs', Dyn%Grid%trs(:,:,nt), grid_domain, timelevel=nt) + endif + if(Dyn%grid_tracer) then + call read_data('INPUT/shallow_dynamics.res.nc', 'tr', Dyn%Grid%tr(:,:,nt), grid_domain, timelevel=nt) + endif + end do +else if(file_exist('INPUT/shallow_dynamics.res')) then + unit = open_restart_file(file='INPUT/shallow_dynamics.res',action='read') + + do nt = 1, 2 + call set_domain(spectral_domain) + call read_data(unit,Dyn%Spec%vor(:,:, nt)) + call read_data(unit,Dyn%Spec%div(:,:, nt)) + call read_data(unit,Dyn%Spec%h (:,:, nt)) + if(Dyn%spec_tracer) call read_data(unit,Dyn%Spec%trs(:,:, nt)) + + call set_domain(grid_domain) + call read_data(unit,Dyn%Grid%u (:,:, nt)) + call read_data(unit,Dyn%Grid%v (:,:, nt)) + call read_data(unit,Dyn%Grid%vor (:,:, nt)) + call read_data(unit,Dyn%Grid%div (:,:, nt)) + call read_data(unit,Dyn%Grid%h (:,:, nt)) + if(Dyn%spec_tracer) call read_data(unit,Dyn%Grid%trs(:,:, nt)) + if(Dyn%grid_tracer) call read_data(unit,Dyn%Grid%tr (:,:, nt)) + + end do + call close_file(unit) + +else + call error_mesg('read_restart', 'restart does not exist', FATAL) +endif + +return +end subroutine read_restart + +!==================================================================== + +subroutine write_restart(Dyn, previous, current) + +type(dynamics_type), intent(in) :: Dyn +integer, intent(in) :: previous, current + +integer :: unit, nt, nn + +do nt = 1, 2 + if(nt == 1) nn = previous + if(nt == 2) nn = current + call write_data('RESTART/shallow_dynamics.res.nc', 'vors_real', real(Dyn%Spec%vor(:,:,nn)), spectral_domain) + call write_data('RESTART/shallow_dynamics.res.nc', 'vors_imag', aimag(Dyn%Spec%vor(:,:,nn)), spectral_domain) + call write_data('RESTART/shallow_dynamics.res.nc', 'divs_real', real(Dyn%Spec%div(:,:,nn)), spectral_domain) + call write_data('RESTART/shallow_dynamics.res.nc', 'divs_imag', aimag(Dyn%Spec%div(:,:,nn)), spectral_domain) + call write_data('RESTART/shallow_dynamics.res.nc', 'hs_real', real(Dyn%Spec%h (:,:,nn)), spectral_domain) + call write_data('RESTART/shallow_dynamics.res.nc', 'hs_imag', aimag(Dyn%Spec%h (:,:,nn)), spectral_domain) + if(Dyn%spec_tracer) then + call write_data('RESTART/shallow_dynamics.res.nc', 'trs_real', real(Dyn%Spec%trs(:,:,nn)), spectral_domain) + call write_data('RESTART/shallow_dynamics.res.nc', 'trs_imag', aimag(Dyn%Spec%trs(:,:,nn)), spectral_domain) + endif + call write_data('RESTART/shallow_dynamics.res.nc', 'u', Dyn%Grid%u (:,:,nn), grid_domain) + call write_data('RESTART/shallow_dynamics.res.nc', 'v', Dyn%Grid%v (:,:,nn), grid_domain) + call write_data('RESTART/shallow_dynamics.res.nc', 'vor', Dyn%Grid%vor(:,:,nn), grid_domain) + call write_data('RESTART/shallow_dynamics.res.nc', 'div', Dyn%Grid%div(:,:,nn), grid_domain) + call write_data('RESTART/shallow_dynamics.res.nc', 'h', Dyn%Grid%h (:,:,nn), grid_domain) + if(Dyn%spec_tracer) then + call write_data('RESTART/shallow_dynamics.res.nc', 'trs', Dyn%Grid%trs(:,:,nn), grid_domain) + endif + if(Dyn%grid_tracer) then + call write_data('RESTART/shallow_dynamics.res.nc', 'tr', Dyn%Grid%tr(:,:,nn), grid_domain) + endif +enddo + +!unit = open_restart_file(file='RESTART/shallow_dynamics.res', action='write') + +!do n = 1, 2 +! if(n == 1) nn = previous +! if(n == 2) nn = current +! +! call set_domain(spectral_domain) +! call write_data(unit,Dyn%Spec%vor(:,:, nn)) +! call write_data(unit,Dyn%Spec%div(:,:, nn)) +! call write_data(unit,Dyn%Spec%h (:,:, nn)) +! if(Dyn%spec_tracer) call write_data(unit,Dyn%Spec%trs(:,:, nn)) +! +! call set_domain(grid_domain) +! call write_data(unit,Dyn%Grid%u (:,:, nn)) +! call write_data(unit,Dyn%Grid%v (:,:, nn)) +! call write_data(unit,Dyn%Grid%vor (:,:, nn)) +! call write_data(unit,Dyn%Grid%div (:,:, nn)) +! call write_data(unit,Dyn%Grid%h (:,:, nn)) +! if(Dyn%spec_tracer) call write_data(unit,Dyn%Grid%trs(:,:, nn)) +! if(Dyn%grid_tracer) call write_data(unit,Dyn%Grid%tr (:,:, nn)) +! +!end do + +!call close_file(unit) + +end subroutine write_restart + +!==================================================================== + +subroutine shallow_dynamics_end (Dyn, previous, current) + +type(dynamics_type), intent(inout) :: Dyn +integer, intent(in) :: previous, current + +if(.not.module_is_initialized) then + call error_mesg('shallow_dynamics_end','dynamics has not been initialized ', FATAL) +endif + +call write_restart (Dyn, previous, current) + +call transforms_end +call stirring_end + +module_is_initialized = .false. + +return +end subroutine shallow_dynamics_end +!=================================================================================== + +end module shallow_dynamics_mod diff --git a/src/atmos_spectral_shallow/shallow_dynamics.html b/src/atmos_spectral_shallow/shallow_dynamics.html new file mode 100644 index 000000000..600933a30 --- /dev/null +++ b/src/atmos_spectral_shallow/shallow_dynamics.html @@ -0,0 +1,370 @@ + +module shallow_dynamics_mod + + +
+ + +module shallow_dynamics_mod
+ + ++ Contact: Isaac Held + Reviewers: Peter Phillipps + ++ + + +
+OVERVIEW
+ ++ + The dynamical core of the spectral transform model for + the shallow water equations on the sphere. + ++ + + +
+DESCRIPTION
+ ++ + Integrates the shallow water equation for hydrostatic flow of a homgeoneous, + incompressible fluid on the + sphere using the spectral transform technique. Also allows for the + inclusion of a passive tracer advected by the the spectral advection + algorithm, and a gridpoint tracer advected with a finite + volume algorithm on the transform grid. Thinking of the model as one of + the upper tropopsheric flow, the default experiment involves relaxation of + the geopotential to an "equilibrium value" with maxima (whose amplitude + and shape are controlled from the namelist) along the equator and in the + subtropicals. + + For a full description of the model and algorithms used, see + shallow.ps + + For higher level routines for running this shallow water model, + see atmosphere_mod + + ++ + + +
+OTHER MODULES USED
+ ++ + fms_mod + constants_mod + time_manager_mod + transforms_mod + spectral_damping_mod + leapfrog_mod + fv_advection_mod + ++ + + +
+PUBLIC INTERFACE
+ ++ + use shallow_dynamics_mod [,only: shallow_dynamics_init, + shallow_dynamics, + shallow_dynamics_end, + dynamics_type, + grid_type, + spectral_type, + tendency_type] + ++ + + +
+PUBLIC DATA
+ ++ ++ + + +
+ + +type grid_type + real, pointer, dimension(:,:,:) :: u, v, vor, div, h, trs, tr + real, pointer, dimension(:,:) :: stream, pv +end type + + allocated space for grid fields + + (:,:,:) => (lon, lat, time_level) + (:,:) => (lon, lat) + (lon, lat) on local computational domain + time_level stores the two time levels needed for the + leapfrog step + + u -- eastward velocity (m/s) + v -- northward velocity (m/s) + vor -- vorticity (1/s) + div -- divergence (1/s) + h -- geopotential (m^2/s^2) + trs -- tracer advected spectrally + tr -- tracer advected on grid + pv -- (f + vor)/h, where f = 2*omega*sin(lat) (s/m^2) + stream -- streamfunction (m^2/s) at current time + + + +
+ + +type spectral_type + complex, pointer, dimension(:,:,:) :: vor, div, h, trs +end type + + allocated space for spectral fields + + (:,:,:) => (zonal, meridional, time_level) + + vor -- spectral vorticity + div -- spectral divergence + h -- spectral geopotential + trs -- spectral tracer + +
+ + +type tendency_type + real, pointer, dimension(:,:) :: u, v, h, trs, tr +end type + + allocated space for accumulating tendencies, d/dt, in grid space, + for prognostic variables + + (:,:,:) => (lon, lat) + +
+ + +type dynamics_type + type(grid_type) :: grid + type(spectral_type) :: spec + type(tendency_type) :: tend + integer :: num_lon, num_lat ! size of global domain + logical :: grid_tracer, spec_tracer +end type + + grid_tracer = .true. => tracer with gridpoint advection is beign integrated + similarly for spec_tracer + +
+ +
+PUBLIC ROUTINES
+ ++ +subroutine shallow_dynamics_init +subroutine shallow _dynamics +subroutine shallow_dynamics_end +type (grid_type) +type (spectral_type) +type (tendency_type) +type (dynamics_type) + + + ++ + + ++ + subroutine shallow_dynamics_init(Dyn, Time, Time_init) + + type(dynamics_type), intent(inout) :: Dyn + type containing all dynamical fields and related information + (see type (dynamics_type)) + + type(time_type) , intent(in) :: Time, Time_init + current time and time at which integeration began + time_type defined by time_manager_mod + + + Initializes the module; + Reads restart from 'INPUT/shallow_dynamics.res' if Time = Time_init; + otherwise uses default initial conditions + ++ +
+ + + + subroutine shallow_dynamics & + (Time, Time_init, Dyn, previous, current, future, delta_t) + + type(time_type) , intent(inout) :: Time, Time_init + type(dynamics_type), intent(inout) :: Dyn + integer , intent(in ) :: previous, current, future + real , intent(in ) :: delta_t + + previous, current and future = 1 or 2 + these integers refer to the third dimension of the + three-dimensional fields in Dyn + the fields at time t - delta_t are assumed to be in (:,:,previous) + the fields at time t are assumed to be in (:,:,current) + the fields at time t + delta_t are placed in (:,:,future) + overwriting whatever is already there + + delta_t = time step in seconds + + updates dynamical fields by one time step + + + +
+ + + subroutine shallow_dynamics_end(Dyn, previous, current) + + type(dynamics_type), intent(inout) :: Dyn + integer, intent(in) :: previous, current + + + Terminates module; + writes restart file to 'RESTART/shallow_dynamics.res' + + + + +
+
+NAMELIST
+ ++ +&shallow_dynamics_nml + + integer :: num_lat = 128 + number of latitudes in global grid + + integer :: num_lon = 256 + number of longitudes in global grid + should equal 2*num_lat for Triangular truncation + + integer :: num_fourier = 85 + the retained fourier wavenumber are n*fourier_inc, where + n ranges from 0 to num_fourier + + integer :: num_spherical = 86 + the maximum number of meridional modes for any zonal wavenumber + for triangular truncation, set num_spherical = num_fourier +1 + + integer :: fourier_inc = 1 + creates a "sector" model if fourier_inc > 1; integration domain is + (360 degrees longitude)/fourier_inc + + (the default values listed above define a standard T85 model) + + logical :: check_fourier_imag = .false. + if true, checks to see if fields to be transformed to grid + domain have zero imaginary part to their zonally symmetric + modes; useful for debugging + + logical :: south_to_north = .true. + true => grid runs from south to north + false => grid runs from north to south + + logical :: triangular_trunc = .true. + true => shape of truncation is triangular + false => shape of truncation is rhomboidal + + real :: robert_coeff = 0.04 + x(current) => (1-2r)*x(current) + r*(x(future)+x(previous)) + where r = robert_coeff (non-dimensional) + + real :: robert_coeff_tracer = 0.04 + (same as robert_coeff, but for grid tracer) + + real :: longitude_origin = 0.0 + longitude of first longitude, in degrees + (if you want the westgern boundary of first grid boc to be at + 0.0, set longitude_origin = 0.5*360./float(num_lon)) + + integer :: damping_option = 'resolution_dependent' + integer :: damping_order = 4 + real :: damping_coeff = 1.e-04 + + damping = nu*(del^2)^n where n = damping order + damping_option = 'resolution_dependent' or 'resolution_independent' + = 'resolution_dependent' => nu is set so that the damping rate for the + mode (m=0,n=num_spherical-1) equals damping_coeff (in 1/s) + For triangular truncation, damping_coeff is then the + rate of damping of the highest retained mode + + = 'resolution_independent' => nu = damping_coef + + real :: h_0 = 3.e04 + (m^2)/(s^2) + the initial condition is a state of rest with geopotential = h_0 + (h_0 is also used to determine the part of the divergence equation + that is integrated implicitly) + + logical :: spec_tracer = .true. + logical :: grid_tracer = .true. + spec_tracer = true => a passive tracer is carried that is advected + spectrally, with the same algorithm as the vorticity + grid_tracer = ture => a passive tracer is carried that is advected + on the spectral transform grid by a finite-volume algorithm + (see shallow.ps ) + Both tracers can be carried simultaeneously + + real, dimension(2) :: valid_range_v = -1000., 1000. + A valid range for meridional wind. Model terminates if meridional wind + goes outside the valid range. Allows model to terminate gracefully when, + for example, the model becomes numerically unstable. + ++ + + +
+ERROR MESSAGES
+ ++ + "Dynamics has not been initialized" + -- shallow_dynamics_init must be called before any other + routines in the module are called + + "restart does not exist" + -- Time is not equal to Time_init at initalization, but the file + 'INPUT/shallow_dynamics.res' does not exit + + ++ + + +
+ + diff --git a/src/atmos_spectral_shallow/shallow_physics.F90 b/src/atmos_spectral_shallow/shallow_physics.F90 new file mode 100644 index 000000000..8f8896d2e --- /dev/null +++ b/src/atmos_spectral_shallow/shallow_physics.F90 @@ -0,0 +1,232 @@ +module shallow_physics_mod + +!----------------------------------------------------------------------- +! GNU General Public License +! +! This program is free software; you can redistribute it and/or modify it and +! are expected to follow the terms of the GNU General Public License +! as published by the Free Software Foundation; either version 2 of +! the License, or (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, but WITHOUT +! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +! License for more details. +! +! For the full text of the GNU General Public License, +! write to: Free Software Foundation, Inc., +! 675 Mass Ave, Cambridge, MA 02139, USA. +! or see: http://www.gnu.org/licenses/gpl.html +!----------------------------------------------------------------------- + +use fms_mod, only: open_namelist_file, & + open_restart_file, & + file_exist, & + check_nml_error, & + error_mesg, & + FATAL, WARNING, & + write_version_number, & + mpp_pe, & + mpp_root_pe, & + fms_init, fms_end, & + read_data, & + write_data, & + set_domain, & + close_file, & + stdlog + +use transforms_mod, only: get_sin_lat, get_cos_lat, & + get_deg_lon, get_deg_lat, & + get_wts_lat, & + get_grid_domain, get_spec_domain, & + grid_domain + +use time_manager_mod, only: time_type + +!======================================================================== +implicit none +private +!======================================================================== + +public :: shallow_physics_init, & + shallow_physics, & + shallow_physics_end, & + phys_type + + +! version information +!======================================================================== +character(len=128) :: version = '$Id: shallow_physics.F90,v 10.0 2003/10/24 22:01:02 fms Exp $' +character(len=128) :: tagname = '$Name: siena_201207 $' +!======================================================================== + +type phys_type + real, pointer, dimension(:,:) :: empty=>NULL() +end type + +logical :: module_is_initialized = .false. + +integer :: is, ie, js, je + +integer :: pe +logical :: root + +real, allocatable, dimension(:) :: rad_lat, deg_lat, deg_lon, & + sin_lat, cos_lat, wts_lat + +real, allocatable, dimension(:,:) :: h_eq + +real :: kappa_m, kappa_t + + + +! namelist +!======================================================================== + +real :: fric_damp_time = -20.0 +real :: therm_damp_time = -10.0 +real :: del_h = 1.e04 +real :: h_0 = 3.e04 +real :: h_amp = 2.e04 +real :: h_lon = 90.0 +real :: h_lat = 25.0 +real :: h_width = 15.0 +real :: h_itcz = 1.e05 +real :: itcz_width = 4.0 + +namelist /shallow_physics_nml/ fric_damp_time, therm_damp_time, del_h, h_0, & + h_amp, h_lon, h_lat, h_width, & + itcz_width, h_itcz +!======================================================================== + +contains + +!======================================================================== + +subroutine shallow_physics_init(Phys) + +type(phys_type), intent(inout) :: Phys + +integer :: i, j, unit, ierr, io + +real :: xx, yy, dd + +call write_version_number(version, tagname) + +pe = mpp_pe() +root = (pe == mpp_root_pe()) + +! read the namelist + +if (file_exist('input.nml')) then + unit = open_namelist_file () + ierr=1 + do while (ierr /= 0) + read (unit, nml=shallow_physics_nml, iostat=io, end=10) + ierr = check_nml_error (io, 'shallow_physics_nml') + enddo + 10 call close_file (unit) +endif + +if(fric_damp_time < 0.0) fric_damp_time = - fric_damp_time*86400 +if(therm_damp_time < 0.0) therm_damp_time = - therm_damp_time*86400 + +kappa_m = 0.0 +kappa_t = 0.0 +if( fric_damp_time .ne. 0.0) kappa_m = 1./fric_damp_time +if(therm_damp_time .ne. 0.0) kappa_t = 1./therm_damp_time + +call get_grid_domain(is,ie,js,je) + +allocate ( rad_lat (js:je) ) +allocate ( deg_lat (js:je) ) +allocate ( sin_lat (js:je) ) +allocate ( cos_lat (js:je) ) +allocate ( wts_lat (js:je) ) +allocate ( deg_lon (is:ie) ) +allocate ( h_eq (is:ie,js:je) ) + +call get_wts_lat(wts_lat) +call get_deg_lat(deg_lat) +call get_deg_lon(deg_lon) +rad_lat = deg_lat*atan(1.)/45. +sin_lat = sin(rad_lat) +cos_lat = cos(rad_lat) + + +do j = js, je + do i = is, ie + xx = (deg_lon(i) - h_lon)/(h_width*2.0) + yy = (deg_lat(j) - h_lat)/h_width + dd = xx*xx + yy*yy + h_eq(i,j) = h_0 + h_amp*max(1.e-10, exp(-dd)) + end do +end do + +do j = js, je + yy = deg_lat(j)/itcz_width + dd = yy*yy + h_eq(:,j) = h_eq(:,j) + h_itcz*exp(-dd) +end do + +!if(file_exist('INPUT/shallow_physics.res')) then +! unit = open_restart_file(file='INPUT/shallow_physics.res',action='read') +! call set_domain(grid_domain) +! call close_file(unit) +!else + +!endif + +module_is_initialized = .true. + +return +end subroutine shallow_physics_init + +!======================================================================= + +subroutine shallow_physics(Time, dt_ug, dt_vg, dt_hg, ug, vg, hg, & + delta_t, previous, current, Phys) + +real, intent(inout), dimension(is:ie, js:je) :: dt_ug, dt_vg, dt_hg +real, intent(in) , dimension(is:ie, js:je, 2) :: ug, vg, hg + +real , intent(in) :: delta_t +integer, intent(in) :: previous, current + +type(time_type), intent(in) :: Time +type(phys_type), intent(inout) :: Phys + +dt_ug = dt_ug - kappa_m*ug(:,:,previous) +dt_vg = dt_vg - kappa_m*vg(:,:,previous) +dt_hg = dt_hg - kappa_t*(hg(:,:,previous) - h_eq) + + +return +end subroutine shallow_physics + +!====================================================================== + +subroutine shallow_physics_end(Phys) + +type(phys_type), intent(in) :: Phys + +integer :: unit + +if(.not.module_is_initialized) then + call error_mesg('shallow_physics_end','physics has not been initialized ', FATAL) +endif + +!unit = open_restart_file(file='RESTART/shallow_physics.res', action='write') + +!call set_domain(grid_domain) + +!call close_file(unit) + +module_is_initialized = .false. + +return +end subroutine shallow_physics_end + +!====================================================================== + +end module shallow_physics_mod diff --git a/src/atmos_spectral_shallow/shallow_physics.html b/src/atmos_spectral_shallow/shallow_physics.html new file mode 100644 index 000000000..d3ad34980 --- /dev/null +++ b/src/atmos_spectral_shallow/shallow_physics.html @@ -0,0 +1,210 @@ + +module shallow_physics_mod + + +
+ + +module shallow_physics_mod
+ + ++ Contact: Isaac Held + Reviewers: Peter Phillipps + ++ + + +
+OVERVIEW
+ ++ + A module that allows one to add processes that act in the grid domain + to the dynamics of the shallow model on the sphere + ++ + + +
+DESCRIPTION
+ ++ + A module that allows one to add processes that act in the grid domain + to the dynamics of the shallow model on the sphere. Currently adds + a relaxation to a specified "equilibrium geopotential" and relaxes + the winds to zero ++ + + +
+OTHER MODULES USED
+ ++ + fms_mod + transforms_mod + time_manager_mod + ++ + + +
+PUBLIC INTERFACE
+ ++ + use shallow_physics_mod [,only: shallow_physics_init, + shallow_physics, + shallow_physics_end, + phys_type] + ++ + + +
+PUBLIC DATA
+ ++ ++ + + +
+ + +type phys_type + real, pointer, dimension(:,:) :: empty +end type + + fields from physics module made available for diagnostics + +
+ + +
+PUBLIC ROUTINES
+ ++ +subroutine shallow_physics_init +subroutine shallow_physics +subroutine shallow_physics_end +type(phys_type) + + + ++ + + + ++ + subroutine shallow_physics_init(Phys) + + type(phys_type) , intent(inout) :: Phys + + + Initializes module + ++ +
+ + + + subroutine shallow_physics (Time, dt_ug, dt_vg, dt_hg, ug, vg, hg, & + delta_t, previous, current, Phys) + + real, intent(inout), dimension(:,:) :: dt_ug, dt_vg, dt_hg + + the u, v and geopotential tendencies onto which tendencies due to + the grid-point physics are added (m/(s^2) for dt_ug, dt_vg; + (m^2)/(s^3) for dt_hg) + + real, intent(in) , dimension(:,:, 2) :: ug, vg, hg + the grid zonal and meridional velocities (m/s) and + geopotential (m^2/s^2) + the third index is the time-index used in the leapfrog step + + real , intent(in) :: delta_t + time step (s) + + integer, intent(in) :: previous, current + = 1 or 2 + ug(:,:,previous) is the velocity at t-delta_t + ug(:,:,current ) is the velocity at t + + type(time_type), intent(in) :: Time + type(phys_type), intent(inout) :: Phys + + + + +
+ + + + subroutine shallow_physics_end (Phys) + + type(phys_type), intent(inout) :: Phys + + + +
+
+NAMELIST
+ ++ +&shallow_physics_nml + +real :: fric_damp_time = -20.0 + rate at which ua nd v are relaxed to zero (seconds) + (if negative, units are days instead -- negative sign is ignored) + +real :: therm_damp_time = -10.0 + rate at which geopotential is relaxed to h_eq + (units as above) + +real :: h_0 = 3.e04 (m^2/s^2) +real :: h_amp = 2.e04 (m^2/s^2) +real :: h_lon = 90.0 degrees +real :: h_lat = 25.0 degrees +real :: h_width = 15.0 degrees +real :: h_itcz = 1.e05 (m^2/s^2) +real :: itcz_width = 4.0 degrees + + h_eq is defined as + h_0 + h_amp*exp(-r^2) + h_itcz*exp(-d^2) + + where r^2 = xx^2 + yy^2 + xx = (lon - h_lon)/(2*h_width) + yy = (lat - h_lat)/h_width + + and d = lat/itcz_width + + ++ + + +
+ + + diff --git a/src/coupler/surface_flux.F90 b/src/coupler/surface_flux.F90 index 97a207f51..d38850528 100644 --- a/src/coupler/surface_flux.F90 +++ b/src/coupler/surface_flux.F90 @@ -261,11 +261,11 @@ module surface_flux_mod logical :: raoult_sat_vap = .false. logical :: do_simple = .false. -real :: land_humidity_prefactor = 1.0 !s Default is that land makes no difference to evaporative fluxes -real :: land_evap_prefactor = 1.0 !s Default is that land makes no difference to evaporative fluxes +real :: land_humidity_prefactor = 1.0 ! Default is that land makes no difference to evaporative fluxes +real :: land_evap_prefactor = 1.0 ! Default is that land makes no difference to evaporative fluxes -real :: flux_heat_gp = 5.7 !s Default value for Jupiter of 5.7 Wm^-2 -real :: diabatic_acce = 1.0 !s Diabatic acceleration?? +real :: flux_heat_gp = 5.7 ! Default value for Jupiter of 5.7 Wm^-2 +real :: diabatic_acce = 1.0 ! Diabatic acceleration?? namelist /surface_flux_nml/ no_neg_q, & @@ -279,10 +279,10 @@ module surface_flux_mod ncar_ocean_flux_orig, & raoult_sat_vap, & do_simple, & - land_humidity_prefactor, & !s Added to make land 'dry', i.e. to decrease the evaporative heat flux in areas of land. - land_evap_prefactor, & !s Added to make land 'dry', i.e. to decrease the evaporative heat flux in areas of land. - flux_heat_gp, & !s prescribed lower boundary heat flux on a giant planet - diabatic_acce + land_humidity_prefactor, & ! Added to make land 'dry', i.e. to decrease the evaporative heat flux in areas of land. + land_evap_prefactor, & ! Added to make land 'dry', i.e. to decrease the evaporative heat flux in areas of land. + flux_heat_gp, & ! prescribed lower boundary heat flux on a giant planet + diabatic_acce @@ -338,8 +338,8 @@ module surface_flux_mod subroutine surface_flux_1d ( & t_atm, q_atm_in, u_atm, v_atm, p_atm, z_atm, & p_surf, t_surf, t_ca, q_surf, & - bucket, bucket_depth, max_bucket_depth_land, & !RG Add bucket - depth_change_lh_1d, depth_change_conv_1d, depth_change_cond_1d, & !RG Add bucket + bucket, bucket_depth, max_bucket_depth_land, & + depth_change_lh_1d, depth_change_conv_1d, depth_change_cond_1d, & u_surf, v_surf, & rough_mom, rough_heat, rough_moist, rough_scale, gust, & flux_t, flux_q, flux_r, flux_u, flux_v, & @@ -347,16 +347,16 @@ subroutine surface_flux_1d ( & w_atm, u_star, b_star, q_star, & dhdt_surf, dedt_surf, dedq_surf, drdt_surf, & dhdt_atm, dedq_atm, dtaudu_atm, dtaudv_atm, & - ex_del_m, ex_del_h, ex_del_q, & !mp586 for 10m winds and 2m temp - temp_2m, u_10m, v_10m, & !mp586 for 10m winds and 2m temp - q_2m, rh_2m, & !Add 2m q and RH + ex_del_m, ex_del_h, ex_del_q, & + temp_2m, u_10m, v_10m, & + q_2m, rh_2m, & dt, land, seawater, avail ) ! ! slm Mar 28 2002 -- remove agument drag_q since it is just cd_q*wind ! ============================================================================ ! ---- arguments ----------------------------------------------------------- logical, intent(in), dimension(:) :: land, seawater, avail - logical, intent(in) :: bucket !RG Add bucket + logical, intent(in) :: bucket ! Add bucket model real, intent(in), dimension(:) :: & t_atm, q_atm_in, u_atm, v_atm, & p_atm, z_atm, t_ca, & @@ -368,22 +368,22 @@ subroutine surface_flux_1d ( & dhdt_atm, dedq_atm, dtaudu_atm,dtaudv_atm, & w_atm, u_star, b_star, q_star, & cd_m, cd_t, cd_q, & - ex_del_m, ex_del_h, ex_del_q, & !mp586 for 10m winds and 2m temp - temp_2m, u_10m, v_10m, & !mp586 for 10m winds and 2m temp - q_2m, rh_2m ! Add 2m q and RH + ex_del_m, ex_del_h, ex_del_q, & + temp_2m, u_10m, v_10m, & + q_2m, rh_2m real, intent(inout), dimension(:) :: q_surf - real, intent(inout), dimension(:) :: bucket_depth !RG Add bucket - real, intent(inout), dimension(:) :: depth_change_lh_1d !RG Add bucket - real, intent(in), dimension(:) :: depth_change_conv_1d, depth_change_cond_1d !RG Add bucket + real, intent(inout), dimension(:) :: bucket_depth + real, intent(inout), dimension(:) :: depth_change_lh_1d + real, intent(in), dimension(:) :: depth_change_conv_1d, depth_change_cond_1d real, intent(in) :: max_bucket_depth_land real, intent(in) :: dt ! ---- local constants ----------------------------------------------------- ! temperature increment and its reciprocal value for comp. of derivatives real, parameter:: del_temp=0.1, del_temp_inv=1.0/del_temp - real:: zrefm, zrefh !mp586 for 10m winds and 2m temp + real:: zrefm, zrefh ! ---- local vars ---------------------------------------------------------- @@ -432,7 +432,7 @@ subroutine surface_flux_1d ( & ! initilaize surface air humidity according to surface type where (land) ! q_surf0 = q_surf ! land calculates it - q_surf0 = q_sat !s our simplified land evaporation model does not calculate q_surf, so we specify it as q_sat. + q_surf0 = q_sat ! our simplified land evaporation model does not calculate q_surf, so we specify it as q_sat. elsewhere q_surf0 = q_sat ! everything else assumes saturated sfc humidity endwhere @@ -505,9 +505,7 @@ subroutine surface_flux_1d ( & rough_mom, rough_heat, rough_moist, w_atm, & cd_m, cd_t, cd_q, u_star, b_star, avail ) -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!!!!!! added by mp586 for 10m winds and 2m temperature add mo_profile()!!!!!!!! - +! added for 10m winds and 2m temperature add mo_profile() zrefm = 10. !want winds at 10m zrefh = 2. !want temp and q at 2m @@ -517,10 +515,8 @@ subroutine surface_flux_1d ( & u_star, b_star, q_star, & ex_del_m, ex_del_h, ex_del_q, avail ) - ! adapted from https://github.com/mom-ocean/MOM5/blob/3702ad86f9653f4e315b98613eb824a47d89cf00/src/coupler/flux_exchange.F90#L1932 - ! ------- reference temp ----------- where (avail) & temp_2m = t_surf + (t_atm - t_surf) * ex_del_h !t_ca = canopy temperature, assuming that there is no canopy (no difference between land and ocean), t_ca = t_surf @@ -533,8 +529,8 @@ subroutine surface_flux_1d ( & where (avail) & v_10m = v_atm * ex_del_m ! setting v at surface to 0. -!!!!!!!!!!!! end of mp586 additions !!!!!!!!!!!!!!!!!!!!!!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! end of low level wind additions + ! Add 2m q and RH @@ -584,29 +580,29 @@ subroutine surface_flux_1d ( & ! evaporation rho_drag = drag_q * rho - end where + end where -!RG Add bucket - if bucket is on evaluate fluxes based on moisture availability. -!RG Note changes to avail statements to allow bucket to be switched on or off +! Add bucket - if bucket is on evaluate fluxes based on moisture availability. +! Note changes to avail statements to allow bucket to be switched on or off if (bucket) then where (avail) ! begin LJJ addition where(land) where (bucket_depth >= max_bucket_depth_land*0.75) flux_q = rho_drag * (q_surf0 - q_atm) - elsewhere + elsewhere flux_q = bucket_depth/(max_bucket_depth_land*0.75) * rho_drag * (q_surf0 - q_atm) ! flux of water vapor (Kg/(m**2 s)) end where elsewhere flux_q = rho_drag * (q_surf0 - q_atm) ! flux of water vapor (Kg/(m**2 s)) end where - - depth_change_lh_1d = flux_q * dt/dens_h2o + + depth_change_lh_1d = flux_q * dt/dens_h2o where (flux_q > 0.0 .and. bucket_depth < depth_change_lh_1d) ! where more evaporation than what's in bucket, empty bucket flux_q = bucket_depth * dens_h2o / dt depth_change_lh_1d = flux_q * dt / dens_h2o - end where - + end where + where (bucket_depth <= 0.0) dedt_surf = 0. dedq_surf = 0. @@ -623,19 +619,19 @@ subroutine surface_flux_1d ( & elsewhere dedt_surf = rho_drag * (q_sat1 - q_sat) *del_temp_inv end where - + end where - end where + end where else -!RG otherwise revert to simple land model +! otherwise revert to simple land model where (avail) where (land) -!s Simplified land model uses simple prefactor in front of qsurf0. Land is therefore basically the same as sea, but with this prefactor, hence the changes to dedq_surf and dedt_surf also. +! Simplified land model uses simple prefactor in front of qsurf0. Land is therefore basically the same as sea, but with this prefactor, hence the changes to dedq_surf and dedt_surf also. flux_q = rho_drag * land_evap_prefactor * (land_humidity_prefactor*q_surf0 - q_atm) ! flux of water vapor (Kg/(m**2 s)) dedq_surf = 0 dedt_surf = rho_drag * land_evap_prefactor * (land_humidity_prefactor*q_sat1 - q_sat) *del_temp_inv -! dedq_surf = rho_drag +! dedq_surf = rho_drag ! dedt_surf = 0 elsewhere flux_q = rho_drag * (q_surf0 - q_atm) ! flux of water vapor (Kg/(m**2 s)) @@ -646,7 +642,7 @@ subroutine surface_flux_1d ( & end where endif -!RG end Add bucket changes +! end of Add bucket changes where (avail) @@ -713,9 +709,9 @@ subroutine surface_flux_0d ( & w_atm_0, u_star_0, b_star_0, q_star_0, & dhdt_surf_0, dedt_surf_0, dedq_surf_0, drdt_surf_0, & dhdt_atm_0, dedq_atm_0, dtaudu_atm_0, dtaudv_atm_0, & - ex_del_m_0, ex_del_h_0, ex_del_q_0, & !mp586 for 10m winds and 2m temp - temp_2m_0, u_10m_0, v_10m_0, & !mp586 for 10m winds and 2m temp - q_2m_0, rh_2m_0, & !2m q and RH + ex_del_m_0, ex_del_h_0, ex_del_q_0, & + temp_2m_0, u_10m_0, v_10m_0, & + q_2m_0, rh_2m_0, & dt, land_0, seawater_0, avail_0 ) ! ---- arguments ----------------------------------------------------------- @@ -730,9 +726,9 @@ subroutine surface_flux_0d ( & dhdt_surf_0, dedt_surf_0, dedq_surf_0, drdt_surf_0, & dhdt_atm_0, dedq_atm_0, dtaudu_atm_0,dtaudv_atm_0, & w_atm_0, u_star_0, b_star_0, q_star_0, & - cd_m_0, cd_t_0, cd_q_0, & - ex_del_m_0, ex_del_h_0, ex_del_q_0, & !mp586 for 10m winds and 2m temp - temp_2m_0, u_10m_0, v_10m_0, & !mp586 for 10m winds and 2m temp + cd_m_0, cd_t_0, cd_q_0, & + ex_del_m_0, ex_del_h_0, ex_del_q_0, & + temp_2m_0, u_10m_0, v_10m_0, & q_2m_0, rh_2m_0 real, intent(inout) :: q_surf_0 real, intent(in) :: dt @@ -750,16 +746,16 @@ subroutine surface_flux_0d ( & dhdt_surf, dedt_surf, dedq_surf, drdt_surf, & dhdt_atm, dedq_atm, dtaudu_atm,dtaudv_atm, & w_atm, u_star, b_star, q_star, & - cd_m, cd_t, cd_q, & - ex_del_m, ex_del_h, ex_del_q, & !mp586 for 10m winds and 2m temp - temp_2m, u_10m, v_10m, & !mp586 for 10m winds and 2m temp - q_2m, rh_2m !Add 2m q and RH + cd_m, cd_t, cd_q, & + ex_del_m, ex_del_h, ex_del_q, & + temp_2m, u_10m, v_10m, & + q_2m, rh_2m real, dimension(1) :: q_surf - real, dimension(1) :: bucket_depth !RG Add bucket - real, dimension(1) :: depth_change_lh_1d !RG Add bucket - real, dimension(1) :: depth_change_conv_1d, depth_change_cond_1d !RG Add bucket - real :: max_bucket_depth_land !RG Add bucket + real, dimension(1) :: bucket_depth + real, dimension(1) :: depth_change_lh_1d + real, dimension(1) :: depth_change_conv_1d, depth_change_cond_1d + real :: max_bucket_depth_land avail = .true. @@ -787,8 +783,8 @@ subroutine surface_flux_0d ( & call surface_flux_1d ( & t_atm, q_atm, u_atm, v_atm, p_atm, z_atm, & p_surf, t_surf, t_ca, q_surf, & - bucket, bucket_depth, max_bucket_depth_land, & !RG Add bucket - depth_change_lh_1d, depth_change_conv_1d, depth_change_cond_1d, & !RG Add bucket + bucket, bucket_depth, max_bucket_depth_land, & + depth_change_lh_1d, depth_change_conv_1d, depth_change_cond_1d, & u_surf, v_surf, & rough_mom, rough_heat, rough_moist, rough_scale, gust, & flux_t, flux_q, flux_r, flux_u, flux_v, & @@ -796,9 +792,9 @@ subroutine surface_flux_0d ( & w_atm, u_star, b_star, q_star, & dhdt_surf, dedt_surf, dedq_surf, drdt_surf, & dhdt_atm, dedq_atm, dtaudu_atm, dtaudv_atm, & - ex_del_m, ex_del_h, ex_del_q, & !mp586 for 10m winds and 2m temp - temp_2m, u_10m, v_10m, & !mp586 for 10m winds and 2m temp - q_2m, rh_2m, & !Add 2m q and RH + ex_del_m, ex_del_h, ex_del_q, & + temp_2m, u_10m, v_10m, & + q_2m, rh_2m, & dt, land, seawater, avail ) flux_t_0 = flux_t(1) @@ -822,22 +818,22 @@ subroutine surface_flux_0d ( & cd_m_0 = cd_m(1) cd_t_0 = cd_t(1) cd_q_0 = cd_q(1) - ex_del_m_0 = ex_del_m(1) !mp586 for 10m winds and 2m temp - ex_del_h_0 = ex_del_h(1) !mp586 for 10m winds and 2m temp - ex_del_q_0 = ex_del_q(1) !mp586 for 10m winds and 2m temp - temp_2m_0 = temp_2m(1) !mp586 for 10m winds and 2m temp - u_10m_0 = u_10m(1) !mp586 for 10m winds and 2m temp - v_10m_0 = v_10m(1) !mp586 for 10m winds and 2m temp - q_2m_0 = q_2m(1) !Add 2m q - rh_2m_0 = rh_2m(1) !Add 2m RH + ex_del_m_0 = ex_del_m(1) + ex_del_h_0 = ex_del_h(1) + ex_del_q_0 = ex_del_q(1) + temp_2m_0 = temp_2m(1) + u_10m_0 = u_10m(1) + v_10m_0 = v_10m(1) + q_2m_0 = q_2m(1) + rh_2m_0 = rh_2m(1) end subroutine surface_flux_0d subroutine surface_flux_2d ( & t_atm, q_atm_in, u_atm, v_atm, p_atm, z_atm, & p_surf, t_surf, t_ca, q_surf, & - bucket, bucket_depth, max_bucket_depth_land, & !RG Add bucket - depth_change_lh, depth_change_conv, depth_change_cond, & !RG Add bucket + bucket, bucket_depth, max_bucket_depth_land, & + depth_change_lh, depth_change_conv, depth_change_cond, & u_surf, v_surf, & rough_mom, rough_heat, rough_moist, rough_scale, gust, & flux_t, flux_q, flux_r, flux_u, flux_v, & @@ -845,9 +841,9 @@ subroutine surface_flux_2d ( & w_atm, u_star, b_star, q_star, & dhdt_surf, dedt_surf, dedq_surf, drdt_surf, & dhdt_atm, dedq_atm, dtaudu_atm, dtaudv_atm, & - ex_del_m, ex_del_h, ex_del_q, & !mp586 for 10m winds and 2m temp - temp_2m, u_10m, v_10m, & !mp586 for 10m winds and 2m temp - q_2m, rh_2m, & !Add 2m q and RH + ex_del_m, ex_del_h, ex_del_q, & + temp_2m, u_10m, v_10m, & + q_2m, rh_2m, & dt, land, seawater, avail ) ! ---- arguments ----------------------------------------------------------- @@ -863,16 +859,16 @@ subroutine surface_flux_2d ( & dhdt_atm, dedq_atm, dtaudu_atm,dtaudv_atm, & w_atm, u_star, b_star, q_star, & cd_m, cd_t, cd_q, & - ex_del_m, ex_del_h, ex_del_q, & !mp586 for 10m winds and 2m temp - temp_2m, u_10m, v_10m, & !mp586 for 10m winds and 2m temp - q_2m, rh_2m !Add 2m q and RH + ex_del_m, ex_del_h, ex_del_q, & + temp_2m, u_10m, v_10m, & + q_2m, rh_2m real, intent(inout), dimension(:,:) :: q_surf - logical, intent(in) :: bucket !RG Add bucket - real, intent(inout), dimension(:,:) :: bucket_depth ! RG Add bucket - real, intent(inout), dimension(:,:) :: depth_change_lh ! RG Add bucket - real, intent(in), dimension(:,:) :: depth_change_conv, depth_change_cond ! RG Add bucket - real, intent(in) :: max_bucket_depth_land ! RG Add bucket + logical, intent(in) :: bucket + real, intent(inout), dimension(:,:) :: bucket_depth + real, intent(inout), dimension(:,:) :: depth_change_lh + real, intent(in), dimension(:,:) :: depth_change_conv, depth_change_cond + real, intent(in) :: max_bucket_depth_land real, intent(in) :: dt ! ---- local vars ----------------------------------------------------------- @@ -882,8 +878,8 @@ subroutine surface_flux_2d ( & call surface_flux_1d ( & t_atm(:,j), q_atm_in(:,j), u_atm(:,j), v_atm(:,j), p_atm(:,j), z_atm(:,j), & p_surf(:,j), t_surf(:,j), t_ca(:,j), q_surf(:,j), & - bucket, bucket_depth(:,j), max_bucket_depth_land, & !RG Add bucket - depth_change_lh(:,j), depth_change_conv(:,j), depth_change_cond(:,j), & !RG Add bucket + bucket, bucket_depth(:,j), max_bucket_depth_land, & + depth_change_lh(:,j), depth_change_conv(:,j), depth_change_cond(:,j), & u_surf(:,j), v_surf(:,j), & rough_mom(:,j), rough_heat(:,j), rough_moist(:,j), rough_scale(:,j), gust(:,j), & flux_t(:,j), flux_q(:,j), flux_r(:,j), flux_u(:,j), flux_v(:,j), & @@ -891,8 +887,8 @@ subroutine surface_flux_2d ( & w_atm(:,j), u_star(:,j), b_star(:,j), q_star(:,j), & dhdt_surf(:,j), dedt_surf(:,j), dedq_surf(:,j), drdt_surf(:,j), & dhdt_atm(:,j), dedq_atm(:,j), dtaudu_atm(:,j), dtaudv_atm(:,j), & - ex_del_m(:,j), ex_del_h(:,j), ex_del_q(:,j), & !mp586 for 10m winds and 2m temp - temp_2m(:,j), u_10m(:,j), v_10m(:,j), & !mp586 for 10m winds and 2m temp + ex_del_m(:,j), ex_del_h(:,j), ex_del_q(:,j), & + temp_2m(:,j), u_10m(:,j), v_10m(:,j), & q_2m(:,j), rh_2m(:,j), & dt, land(:,j), seawater(:,j), avail(:,j) ) end do @@ -910,6 +906,7 @@ subroutine surface_flux_init ! read namelist #ifdef INTERNAL_FILE_NML read (input_nml_file, surface_flux_nml, iostat=io) + ierr = check_nml_error(io,'surface_flux_nml') #else if ( file_exist('input.nml')) then unit = open_namelist_file () diff --git a/src/extra/env/deepthought2 b/src/extra/env/deepthought2 new file mode 100644 index 000000000..4500ad1b1 --- /dev/null +++ b/src/extra/env/deepthought2 @@ -0,0 +1,13 @@ +echo loadmodules for Deepthought2 + +module load intel/2015.0.3.032 +module load openmpi/1.8.6 +module load netcdf/4.3.3.1 +module load netcdf-fortran + +export NETCDF=$NETCDF_FORTRAN_ROOT +export GFDL_MKMF_TEMPLATE=dt2 +export LD_LIBRARY_PATH=$NETCDF_LIBDIR:$NETCDF_FORTRAN_LIBDIR:$LD_LIBRARY_PATH +export MPI_LIB= +export F90=mpifort +export CC=mpicc diff --git a/src/extra/env/fasrc b/src/extra/env/fasrc new file mode 100644 index 000000000..940299013 --- /dev/null +++ b/src/extra/env/fasrc @@ -0,0 +1,11 @@ +echo loadmodules for Isca on Harvard FASRC Cluster Cannon/Odyssey + +export F90=mpif90; echo $F90; +export CC=mpicc + +module purge +module load intel/17.0.4-fasrc01 +#module load hdf5/1.10.1-fasrc03 +module load intel/17.0.4-fasrc01 openmpi/2.1.0-fasrc02 netcdf-fortran/4.4.4-fasrc06 +module load zlib/1.2.8-fasrc07 +#module load netcdf/4.3.2-fasrc03 diff --git a/src/extra/env/gekko b/src/extra/env/gekko new file mode 100644 index 000000000..3ea79b577 --- /dev/null +++ b/src/extra/env/gekko @@ -0,0 +1,10 @@ +echo loadmodules for Isca on NTU Gekko + +export F90=mpiifort; echo $F90; +export CC=mpiicc + +module purge +module load intel/2018u3 +module load hdf/1.10.0 +module load netcdf-fortran/4.4.4 +module load netcdf/4.6.1 diff --git a/src/extra/env/maths2 b/src/extra/env/maths2 new file mode 100644 index 000000000..e693bc85e --- /dev/null +++ b/src/extra/env/maths2 @@ -0,0 +1,6 @@ +echo loadmodules for maths2 machines + +export F90=mpiifort +export CC=mpiicc + +export GFDL_MKMF_TEMPLATE=maths2 diff --git a/src/extra/env/nyu-prince b/src/extra/env/nyu-prince new file mode 100644 index 000000000..702c4edf9 --- /dev/null +++ b/src/extra/env/nyu-prince @@ -0,0 +1,10 @@ +#!/bin/bash + +echo load modules for Isca on NYU HPC prince system + +export F90=mpif90 +export CC=mpicc + +module purge +module load openmpi/intel/2.0.1 +module load netcdf/intel/4.7.2 diff --git a/src/extra/env/ubuntu_conda b/src/extra/env/ubuntu_conda new file mode 100644 index 000000000..ccbc1cabc --- /dev/null +++ b/src/extra/env/ubuntu_conda @@ -0,0 +1,7 @@ +echo "Loading basic ubuntu-conda environment" + +# this defaults to ia64, but we will use gfortran, not ifort +export GFDL_MKMF_TEMPLATE=ubuntu_conda + +export F90=mpifort +export CC=mpicc diff --git a/src/extra/model/barotropic/field_table b/src/extra/model/barotropic/field_table new file mode 100644 index 000000000..e69de29bb diff --git a/src/extra/model/barotropic/path_names b/src/extra/model/barotropic/path_names new file mode 100644 index 000000000..e7c619d86 --- /dev/null +++ b/src/extra/model/barotropic/path_names @@ -0,0 +1,138 @@ +atmos_solo/atmos_model.F90 +atmos_spectral_barotropic/atmosphere.F90 +atmos_spectral_barotropic/barotropic_diagnostics.F90 +atmos_spectral_barotropic/barotropic_dynamics.F90 +atmos_spectral_barotropic/barotropic_physics.F90 +atmos_spectral_barotropic/stirring.F90 +atmos_spectral/model/fv_advection.F90 +atmos_spectral/model/leapfrog.F90 +atmos_spectral/model/spectral_damping.F90 +atmos_spectral/tools/gauss_and_legendre.F90 +atmos_spectral/tools/grid_fourier.F90 +atmos_spectral/tools/spec_mpp.F90 +atmos_spectral/tools/spherical.F90 +atmos_spectral/tools/spherical_fourier.F90 +atmos_spectral/tools/transforms.F90 +shared/constants/constants.F90 +shared/diag_manager/diag_axis.F90 +shared/diag_manager/diag_data.F90 +shared/diag_manager/diag_grid.F90 +shared/diag_manager/diag_manager.F90 +shared/diag_manager/diag_output.F90 +shared/diag_manager/diag_table.F90 +shared/diag_manager/diag_util.F90 +shared/fft/fft99.F90 +shared/fft/fft.F90 +shared/field_manager/field_manager.F90 +shared/field_manager/fm_util.F90 +shared/field_manager/parse.inc +shared/fms/fms.F90 +shared/fms/fms_io.F90 +shared/fms/read_data_2d.inc +shared/fms/read_data_3d.inc +shared/fms/read_data_4d.inc +shared/fms/test_fms_io.F90 +shared/fms/write_data.inc +shared/include/fms_platform.h +shared/memutils/memuse.c +shared/memutils/memutils.F90 +shared/mosaic/constant.h +shared/mosaic/create_xgrid.c +shared/mosaic/create_xgrid.h +shared/mosaic/gradient_c2l.c +shared/mosaic/gradient_c2l.h +shared/mosaic/gradient.F90 +shared/mosaic/grid.F90 +shared/mosaic/interp.c +shared/mosaic/interp.h +shared/mosaic/mosaic.F90 +shared/mosaic/mosaic_util.c +shared/mosaic/mosaic_util.h +shared/mosaic/read_mosaic.c +shared/mosaic/read_mosaic.h +shared/mpp/affinity.c +shared/mpp/include/mpp_chksum.h +shared/mpp/include/mpp_chksum_int.h +shared/mpp/include/mpp_chksum_scalar.h +shared/mpp/include/mpp_comm.inc +shared/mpp/include/mpp_comm_mpi.inc +shared/mpp/include/mpp_comm_nocomm.inc +shared/mpp/include/mpp_comm_sma.inc +shared/mpp/include/mpp_data_mpi.inc +shared/mpp/include/mpp_data_nocomm.inc +shared/mpp/include/mpp_data_sma.inc +shared/mpp/include/mpp_define_nest_domains.inc +shared/mpp/include/mpp_do_check.h +shared/mpp/include/mpp_do_checkV.h +shared/mpp/include/mpp_do_get_boundary.h +shared/mpp/include/mpp_do_global_field.h +shared/mpp/include/mpp_domains_comm.inc +shared/mpp/include/mpp_domains_define.inc +shared/mpp/include/mpp_domains_misc.inc +shared/mpp/include/mpp_domains_reduce.inc +shared/mpp/include/mpp_domains_util.inc +shared/mpp/include/mpp_do_redistribute.h +shared/mpp/include/mpp_do_update_ad.h +shared/mpp/include/mpp_do_update.h +shared/mpp/include/mpp_do_update_nest.h +shared/mpp/include/mpp_do_update_nonblock.h +shared/mpp/include/mpp_do_updateV_ad.h +shared/mpp/include/mpp_do_updateV.h +shared/mpp/include/mpp_do_updateV_nonblock.h +shared/mpp/include/mpp_error_a_a.h +shared/mpp/include/mpp_error_a_s.h +shared/mpp/include/mpp_error_s_a.h +shared/mpp/include/mpp_error_s_s.h +shared/mpp/include/mpp_gather.h +shared/mpp/include/mpp_get_boundary.h +shared/mpp/include/mpp_global_field.h +shared/mpp/include/mpp_global_reduce.h +shared/mpp/include/mpp_global_sum_ad.h +shared/mpp/include/mpp_global_sum.h +shared/mpp/include/mpp_global_sum_tl.h +shared/mpp/include/mpp_io_connect.inc +shared/mpp/include/mpp_io_misc.inc +shared/mpp/include/mpp_io_read.inc +shared/mpp/include/mpp_io_util.inc +shared/mpp/include/mpp_io_write.inc +shared/mpp/include/mpp_read_2Ddecomp.h +shared/mpp/include/mpp_reduce_mpi.h +shared/mpp/include/mpp_reduce_nocomm.h +shared/mpp/include/mpp_reduce_sma.h +shared/mpp/include/mpp_sum.inc +shared/mpp/include/mpp_sum_mpi.h +shared/mpp/include/mpp_sum_nocomm.h +shared/mpp/include/mpp_sum_sma.h +shared/mpp/include/mpp_transmit.inc +shared/mpp/include/mpp_transmit_mpi.h +shared/mpp/include/mpp_transmit_nocomm.h +shared/mpp/include/mpp_transmit_sma.h +shared/mpp/include/mpp_update_domains2D_ad.h +shared/mpp/include/mpp_update_domains2D.h +shared/mpp/include/mpp_update_domains2D_nonblock.h +shared/mpp/include/mpp_update_nest_domains.h +shared/mpp/include/mpp_util.inc +shared/mpp/include/mpp_util_mpi.inc +shared/mpp/include/mpp_util_nocomm.inc +shared/mpp/include/mpp_util_sma.inc +shared/mpp/include/mpp_write_2Ddecomp.h +shared/mpp/include/mpp_write.h +shared/mpp/include/system_clock.h +shared/mpp/mpp_data.F90 +shared/mpp/mpp_domains.F90 +shared/mpp/mpp.F90 +shared/mpp/mpp_io.F90 +shared/mpp/mpp_memutils.F90 +shared/mpp/mpp_parameter.F90 +shared/mpp/mpp_pset.F90 +shared/mpp/mpp_utilities.F90 +shared/mpp/nsclock.c +shared/mpp/test_mpp_domains.F90 +shared/mpp/test_mpp.F90 +shared/mpp/test_mpp_io.F90 +shared/mpp/test_mpp_pset.F90 +shared/mpp/threadloc.c +shared/platform/platform.F90 +shared/time_manager/get_cal_time.F90 +shared/time_manager/time_manager.F90 +shared/tracer_manager/tracer_manager.F90 diff --git a/src/extra/model/column/field_table b/src/extra/model/column/field_table new file mode 100644 index 000000000..c2d63b9dd --- /dev/null +++ b/src/extra/model/column/field_table @@ -0,0 +1,10 @@ + +"TRACER", "atmos_mod", "sphum" + "longname", "specific humidity" + "units", "kg/kg" + "numerical_representation", "grid" + "hole_filling", "off" + "advect_vert", "finite_volume_parabolic" + "robert_filter", "on" + "profile_type", "fixed", "surface_value=0.0" / + diff --git a/src/extra/model/column/path_names b/src/extra/model/column/path_names new file mode 100644 index 000000000..e270ee283 --- /dev/null +++ b/src/extra/model/column/path_names @@ -0,0 +1,262 @@ +atmos_column/column.F90 +atmos_column/column_init_cond.F90 +atmos_column/column_grid.F90 +atmos_column/column_initialize_fields.F90 +atmos_param/diffusivity/diffusivity.F90 +atmos_param/edt/edt.F90 +atmos_param/entrain/entrain.F90 +atmos_param/hs_forcing/hs_forcing.F90 +atmos_param/lscale_cond/lscale_cond.F90 +atmos_param/my25_turb/my25_turb.F90 +atmos_param/qe_moist_convection/qe_moist_convection.F90 +atmos_param/betts_miller/betts_miller.f90 +atmos_param/ras/ras.f90 +atmos_param/sea_esf_rad/null/rad_utilities.F90 +atmos_param/shallow_conv/shallow_conv.F90 +atmos_param/stable_bl_turb/stable_bl_turb.F90 +atmos_param/strat_cloud/null/strat_cloud.F90 +atmos_param/cloud_simple/cloud_simple.F90 +atmos_param/cloud_simple/lcl.F90 +atmos_param/cloud_simple/large_scale_cloud.F90 +atmos_param/cloud_simple/marine_strat_cloud.F90 +atmos_param/cloud_simple/cloud_cover_diags.F90 +atmos_param/cloud_simple/cloud_spookie.F90 +atmos_param/two_stream_gray_rad/two_stream_gray_rad.F90 +atmos_param/qflux/qflux.f90 +atmos_param/monin_obukhov/monin_obukhov_interfaces.h +atmos_param/monin_obukhov/monin_obukhov_kernel.F90 +atmos_param/monin_obukhov/monin_obukhov.F90 +atmos_param/dry_convection/dry_convection.f90 +atmos_param/rayleigh_bottom_drag/rayleigh_bottom_drag.F90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/parkind.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/parrrtm.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_cld.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_con.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg01.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg02.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg03.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg04.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg05.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg06.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg07.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg08.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg09.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg10.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg11.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg12.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg13.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg14.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg15.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_kg16.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_ncpar.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_ref.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_tbl.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_vsn.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_wvn.f90 +atmos_param/rrtm_radiation/rrtm_radiation.F90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/mcica_random_numbers.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_cldprop.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_rad.nomcica.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_rtrn.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_setcoef.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/mcica_subcol_gen_lw.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_init.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_rtrnmc.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_taumol.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_cldprmc.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_k_g.f90 +atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_rtrnmr.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/parkind.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/parrrsw.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_aer.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_cld.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_con.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg16.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg17.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg18.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg19.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg20.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg21.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg22.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg23.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg24.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg25.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg26.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg27.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg28.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_kg29.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_ncpar.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_ref.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_tbl.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_vsn.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/modules/rrsw_wvn.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/mcica_random_numbers.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/mcica_subcol_gen_sw.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/rrtmg_sw_rad.nomcica.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/rrtmg_sw_cldprop.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/rrtmg_sw_cldprmc.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/rrtmg_sw_init.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/rrtmg_sw_k_g.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/rrtmg_sw_reftra.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/rrtmg_sw_setcoef.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/rrtmg_sw_spcvrt.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/rrtmg_sw_spcvmc.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/rrtmg_sw_taumol.f90 +atmos_param/rrtm_radiation/rrtmg_sw/gcm_model/src/rrtmg_sw_vrtqdr.f90 +atmos_param/damping_driver/damping_driver.f90 +atmos_param/mg_drag/mg_drag.f90 +atmos_param/cg_drag/cg_drag.f90 +atmos_param/topo_drag/topo_drag.f90 +atmos_param/vert_diff/vert_diff.F90 +atmos_param/vert_turb_driver/vert_turb_driver.F90 +atmos_shared/interpolator/interpolator.F90 +atmos_shared/vert_advection/vert_advection.F90 +atmos_solo/atmos_model.F90 +atmos_spectral/driver/solo/atmosphere.F90 +atmos_spectral/driver/solo/idealized_moist_phys.F90 +atmos_spectral/driver/solo/mixed_layer.F90 +atmos_spectral/init/vert_coordinate.F90 +atmos_spectral/model/press_and_geopot.F90 +atmos_spectral/model/tracer_type.F90 +atmos_spectral/tools/spec_mpp.F90 +coupler/surface_flux.F90 +shared/axis_utils/axis_utils.F90 +shared/constants/constants.F90 +shared/astronomy/astronomy.f90 +shared/diag_manager/diag_axis.F90 +shared/diag_manager/diag_data.F90 +shared/diag_manager/diag_grid.F90 +shared/diag_manager/diag_manager.F90 +shared/diag_manager/diag_output.F90 +shared/diag_manager/diag_table.F90 +shared/diag_manager/diag_util.F90 +shared/fft/fft99.F90 +shared/fft/fft.F90 +shared/field_manager/field_manager.F90 +shared/field_manager/fm_util.F90 +shared/field_manager/parse.inc +shared/fms/fms.F90 +shared/fms/fms_io.F90 +shared/fms/read_data_2d.inc +shared/fms/read_data_3d.inc +shared/fms/read_data_4d.inc +shared/fms/test_fms_io.F90 +shared/fms/write_data.inc +shared/horiz_interp/horiz_interp_bicubic.F90 +shared/horiz_interp/horiz_interp_bilinear.F90 +shared/horiz_interp/horiz_interp_conserve.F90 +shared/horiz_interp/horiz_interp.F90 +shared/horiz_interp/horiz_interp_spherical.F90 +shared/horiz_interp/horiz_interp_type.F90 +shared/include/fms_platform.h +shared/memutils/memuse.c +shared/memutils/memutils.F90 +shared/mosaic/constant.h +shared/mosaic/create_xgrid.c +shared/mosaic/create_xgrid.h +shared/mosaic/gradient_c2l.c +shared/mosaic/gradient_c2l.h +shared/mosaic/gradient.F90 +shared/mosaic/grid.F90 +shared/mosaic/interp.c +shared/mosaic/interp.h +shared/mosaic/mosaic.F90 +shared/mosaic/mosaic_util.c +shared/mosaic/mosaic_util.h +shared/mosaic/read_mosaic.c +shared/mosaic/read_mosaic.h +shared/mpp/affinity.c +shared/mpp/include/mpp_chksum.h +shared/mpp/include/mpp_chksum_int.h +shared/mpp/include/mpp_chksum_scalar.h +shared/mpp/include/mpp_comm.inc +shared/mpp/include/mpp_comm_mpi.inc +shared/mpp/include/mpp_comm_nocomm.inc +shared/mpp/include/mpp_comm_sma.inc +shared/mpp/include/mpp_data_mpi.inc +shared/mpp/include/mpp_data_nocomm.inc +shared/mpp/include/mpp_data_sma.inc +shared/mpp/include/mpp_define_nest_domains.inc +shared/mpp/include/mpp_do_check.h +shared/mpp/include/mpp_do_checkV.h +shared/mpp/include/mpp_do_get_boundary.h +shared/mpp/include/mpp_do_global_field.h +shared/mpp/include/mpp_domains_comm.inc +shared/mpp/include/mpp_domains_define.inc +shared/mpp/include/mpp_domains_misc.inc +shared/mpp/include/mpp_domains_reduce.inc +shared/mpp/include/mpp_domains_util.inc +shared/mpp/include/mpp_do_redistribute.h +shared/mpp/include/mpp_do_update_ad.h +shared/mpp/include/mpp_do_update.h +shared/mpp/include/mpp_do_update_nest.h +shared/mpp/include/mpp_do_update_nonblock.h +shared/mpp/include/mpp_do_updateV_ad.h +shared/mpp/include/mpp_do_updateV.h +shared/mpp/include/mpp_do_updateV_nonblock.h +shared/mpp/include/mpp_error_a_a.h +shared/mpp/include/mpp_error_a_s.h +shared/mpp/include/mpp_error_s_a.h +shared/mpp/include/mpp_error_s_s.h +shared/mpp/include/mpp_gather.h +shared/mpp/include/mpp_get_boundary.h +shared/mpp/include/mpp_global_field.h +shared/mpp/include/mpp_global_reduce.h +shared/mpp/include/mpp_global_sum_ad.h +shared/mpp/include/mpp_global_sum.h +shared/mpp/include/mpp_global_sum_tl.h +shared/mpp/include/mpp_io_connect.inc +shared/mpp/include/mpp_io_misc.inc +shared/mpp/include/mpp_io_read.inc +shared/mpp/include/mpp_io_util.inc +shared/mpp/include/mpp_io_write.inc +shared/mpp/include/mpp_read_2Ddecomp.h +shared/mpp/include/mpp_reduce_mpi.h +shared/mpp/include/mpp_reduce_nocomm.h +shared/mpp/include/mpp_reduce_sma.h +shared/mpp/include/mpp_sum.inc +shared/mpp/include/mpp_sum_mpi.h +shared/mpp/include/mpp_sum_nocomm.h +shared/mpp/include/mpp_sum_sma.h +shared/mpp/include/mpp_transmit.inc +shared/mpp/include/mpp_transmit_mpi.h +shared/mpp/include/mpp_transmit_nocomm.h +shared/mpp/include/mpp_transmit_sma.h +shared/mpp/include/mpp_update_domains2D_ad.h +shared/mpp/include/mpp_update_domains2D.h +shared/mpp/include/mpp_update_domains2D_nonblock.h +shared/mpp/include/mpp_update_nest_domains.h +shared/mpp/include/mpp_util.inc +shared/mpp/include/mpp_util_mpi.inc +shared/mpp/include/mpp_util_nocomm.inc +shared/mpp/include/mpp_util_sma.inc +shared/mpp/include/mpp_write_2Ddecomp.h +shared/mpp/include/mpp_write.h +shared/mpp/include/system_clock.h +shared/mpp/mpp_data.F90 +shared/mpp/mpp_domains.F90 +shared/mpp/mpp.F90 +shared/mpp/mpp_io.F90 +shared/mpp/mpp_memutils.F90 +shared/mpp/mpp_parameter.F90 +shared/mpp/mpp_pset.F90 +shared/mpp/mpp_utilities.F90 +shared/mpp/nsclock.c +shared/mpp/test_mpp_domains.F90 +shared/mpp/test_mpp.F90 +shared/mpp/test_mpp_io.F90 +shared/mpp/test_mpp_pset.F90 +shared/mpp/threadloc.c +shared/platform/platform.F90 +shared/random_numbers/MersenneTwister.F90 +shared/random_numbers/random_numbers.F90 +shared/sat_vapor_pres/sat_vapor_pres.F90 +shared/sat_vapor_pres/sat_vapor_pres_k.F90 +shared/time_interp/time_interp_external.F90 +shared/time_interp/time_interp.F90 +shared/time_manager/get_cal_time.F90 +shared/time_manager/time_manager.F90 +shared/topography/gaussian_topog.F90 +shared/topography/topography.F90 +shared/tracer_manager/tracer_manager.F90 +shared/tridiagonal/tridiagonal.F90 diff --git a/src/extra/model/dry/path_names b/src/extra/model/dry/path_names index 635b45dfc..6a974f397 100644 --- a/src/extra/model/dry/path_names +++ b/src/extra/model/dry/path_names @@ -8,6 +8,12 @@ atmos_param/qe_moist_convection/qe_moist_convection.F90 atmos_param/betts_miller/betts_miller.f90 atmos_param/sea_esf_rad/null/rad_utilities.F90 atmos_param/shallow_conv/shallow_conv.F90 +atmos_param/cloud_simple/cloud_simple.F90 +atmos_param/cloud_simple/lcl.F90 +atmos_param/cloud_simple/large_scale_cloud.F90 +atmos_param/cloud_simple/marine_strat_cloud.F90 +atmos_param/cloud_simple/cloud_cover_diags.F90 +atmos_param/cloud_simple/cloud_spookie.F90 atmos_param/stable_bl_turb/stable_bl_turb.F90 atmos_param/strat_cloud/null/strat_cloud.F90 atmos_param/two_stream_gray_rad/two_stream_gray_rad.F90 diff --git a/src/extra/model/grey/path_names b/src/extra/model/grey/path_names index 96bc7b6bf..1bdea444c 100644 --- a/src/extra/model/grey/path_names +++ b/src/extra/model/grey/path_names @@ -10,6 +10,12 @@ atmos_param/sea_esf_rad/null/rad_utilities.F90 atmos_param/shallow_conv/shallow_conv.F90 atmos_param/stable_bl_turb/stable_bl_turb.F90 atmos_param/strat_cloud/null/strat_cloud.F90 +atmos_param/cloud_simple/cloud_simple.F90 +atmos_param/cloud_simple/lcl.F90 +atmos_param/cloud_simple/large_scale_cloud.F90 +atmos_param/cloud_simple/marine_strat_cloud.F90 +atmos_param/cloud_simple/cloud_cover_diags.F90 +atmos_param/cloud_simple/cloud_spookie.F90 atmos_param/two_stream_gray_rad/two_stream_gray_rad.F90 atmos_param/qflux/qflux.f90 atmos_param/monin_obukhov/monin_obukhov_interfaces.h diff --git a/src/extra/model/isca/path_names b/src/extra/model/isca/path_names index ee73b2499..4b08c4edb 100644 --- a/src/extra/model/isca/path_names +++ b/src/extra/model/isca/path_names @@ -11,6 +11,12 @@ atmos_param/sea_esf_rad/null/rad_utilities.F90 atmos_param/shallow_conv/shallow_conv.F90 atmos_param/stable_bl_turb/stable_bl_turb.F90 atmos_param/strat_cloud/null/strat_cloud.F90 +atmos_param/cloud_simple/cloud_simple.F90 +atmos_param/cloud_simple/lcl.F90 +atmos_param/cloud_simple/large_scale_cloud.F90 +atmos_param/cloud_simple/marine_strat_cloud.F90 +atmos_param/cloud_simple/cloud_cover_diags.F90 +atmos_param/cloud_simple/cloud_spookie.F90 atmos_param/two_stream_gray_rad/two_stream_gray_rad.F90 atmos_param/qflux/qflux.f90 atmos_param/monin_obukhov/monin_obukhov_interfaces.h @@ -43,7 +49,7 @@ atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_ref.f90 atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_tbl.f90 atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_vsn.f90 atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/modules/rrlw_wvn.f90 -atmos_param/rrtm_radiation/rrtm_radiation.f90 +atmos_param/rrtm_radiation/rrtm_radiation.F90 atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/mcica_random_numbers.f90 atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_cldprop.f90 atmos_param/rrtm_radiation/rrtmg_lw/gcm_model/src/rrtmg_lw_rad.nomcica.f90 diff --git a/src/extra/model/shallow/path_names b/src/extra/model/shallow/path_names new file mode 100644 index 000000000..02dbdac8a --- /dev/null +++ b/src/extra/model/shallow/path_names @@ -0,0 +1,148 @@ +atmos_solo/atmos_model.F90 +atmos_spectral/model/fv_advection.F90 +atmos_spectral/model/leapfrog.F90 +atmos_spectral/model/spectral_damping.F90 +atmos_spectral_shallow/atmosphere.F90 +atmos_spectral_shallow/shallow_diagnostics.F90 +atmos_spectral_shallow/shallow_dynamics.F90 +atmos_spectral_shallow/shallow_physics.F90 +atmos_spectral_barotropic/stirring.F90 +atmos_spectral/tools/gauss_and_legendre.F90 +atmos_spectral/tools/grid_fourier.F90 +atmos_spectral/tools/spec_mpp.F90 +atmos_spectral/tools/spherical.F90 +atmos_spectral/tools/spherical_fourier.F90 +atmos_spectral/tools/transforms.F90 +shared/constants/constants.F90 +shared/diag_manager/diag_axis.F90 +shared/diag_manager/diag_data.F90 +shared/diag_manager/diag_grid.F90 +shared/diag_manager/diag_manager.F90 +shared/diag_manager/diag_output.F90 +shared/diag_manager/diag_table.F90 +shared/diag_manager/diag_util.F90 +shared/fft/fft99.F90 +shared/fft/fft.F90 +shared/field_manager/field_manager.F90 +shared/field_manager/fm_util.F90 +shared/field_manager/parse.inc +shared/fms/fms.F90 +shared/fms/fms_io.F90 +shared/fms/read_data_2d.inc +shared/fms/read_data_3d.inc +shared/fms/read_data_4d.inc +shared/fms/test_fms_io.F90 +shared/fms/write_data.inc +shared/include/fms_platform.h +shared/memutils/memuse.c +shared/memutils/memutils.F90 +shared/mosaic/constant.h +shared/mosaic/create_xgrid.c +shared/mosaic/create_xgrid.h +shared/mosaic/gradient_c2l.c +shared/mosaic/gradient_c2l.h +shared/mosaic/gradient.F90 +shared/mosaic/grid.F90 +shared/mosaic/interp.c +shared/mosaic/interp.h +shared/mosaic/mosaic.F90 +shared/mosaic/mosaic_util.c +shared/mosaic/mosaic_util.h +shared/mosaic/read_mosaic.c +shared/mosaic/read_mosaic.h +shared/mpp/affinity.c +shared/mpp/include/mpp_chksum.h +shared/mpp/include/mpp_chksum_int.h +shared/mpp/include/mpp_chksum_scalar.h +shared/mpp/include/mpp_comm.inc +shared/mpp/include/mpp_comm_mpi.inc +shared/mpp/include/mpp_comm_nocomm.inc +shared/mpp/include/mpp_comm_sma.inc +shared/mpp/include/mpp_data_mpi.inc +shared/mpp/include/mpp_data_nocomm.inc +shared/mpp/include/mpp_data_sma.inc +shared/mpp/include/mpp_define_nest_domains.inc +shared/mpp/include/mpp_do_check.h +shared/mpp/include/mpp_do_checkV.h +shared/mpp/include/mpp_do_get_boundary.h +shared/mpp/include/mpp_do_global_field.h +shared/mpp/include/mpp_domains_comm.inc +shared/mpp/include/mpp_domains_define.inc +shared/mpp/include/mpp_domains_misc.inc +shared/mpp/include/mpp_domains_reduce.inc +shared/mpp/include/mpp_domains_util.inc +shared/mpp/include/mpp_do_redistribute.h +shared/mpp/include/mpp_do_update_ad.h +shared/mpp/include/mpp_do_update.h +shared/mpp/include/mpp_do_update_nest.h +shared/mpp/include/mpp_do_update_nonblock.h +shared/mpp/include/mpp_do_updateV_ad.h +shared/mpp/include/mpp_do_updateV.h +shared/mpp/include/mpp_do_updateV_nonblock.h +shared/mpp/include/mpp_error_a_a.h +shared/mpp/include/mpp_error_a_s.h +shared/mpp/include/mpp_error_s_a.h +shared/mpp/include/mpp_error_s_s.h +shared/mpp/include/mpp_gather.h +shared/mpp/include/mpp_get_boundary.h +shared/mpp/include/mpp_global_field.h +shared/mpp/include/mpp_global_reduce.h +shared/mpp/include/mpp_global_sum_ad.h +shared/mpp/include/mpp_global_sum.h +shared/mpp/include/mpp_global_sum_tl.h +shared/mpp/include/mpp_io_connect.inc +shared/mpp/include/mpp_io_misc.inc +shared/mpp/include/mpp_io_read.inc +shared/mpp/include/mpp_io_util.inc +shared/mpp/include/mpp_io_write.inc +shared/mpp/include/mpp_read_2Ddecomp.h +shared/mpp/include/mpp_reduce_mpi.h +shared/mpp/include/mpp_reduce_nocomm.h +shared/mpp/include/mpp_reduce_sma.h +shared/mpp/include/mpp_sum.inc +shared/mpp/include/mpp_sum_mpi.h +shared/mpp/include/mpp_sum_nocomm.h +shared/mpp/include/mpp_sum_sma.h +shared/mpp/include/mpp_transmit.inc +shared/mpp/include/mpp_transmit_mpi.h +shared/mpp/include/mpp_transmit_nocomm.h +shared/mpp/include/mpp_transmit_sma.h +shared/mpp/include/mpp_update_domains2D_ad.h +shared/mpp/include/mpp_update_domains2D.h +shared/mpp/include/mpp_update_domains2D_nonblock.h +shared/mpp/include/mpp_update_nest_domains.h +shared/mpp/include/mpp_util.inc +shared/mpp/include/mpp_util_mpi.inc +shared/mpp/include/mpp_util_nocomm.inc +shared/mpp/include/mpp_util_sma.inc +shared/mpp/include/mpp_write_2Ddecomp.h +shared/mpp/include/mpp_write.h +shared/mpp/include/system_clock.h +shared/mpp/mpp_data.F90 +shared/mpp/mpp_domains.F90 +shared/mpp/mpp.F90 +shared/mpp/mpp_io.F90 +shared/mpp/mpp_memutils.F90 +shared/mpp/mpp_parameter.F90 +shared/mpp/mpp_pset.F90 +shared/mpp/mpp_utilities.F90 +shared/mpp/nsclock.c +shared/mpp/test_mpp_domains.F90 +shared/mpp/test_mpp.F90 +shared/mpp/test_mpp_io.F90 +shared/mpp/test_mpp_pset.F90 +shared/mpp/threadloc.c +shared/platform/platform.F90 +shared/time_manager/get_cal_time.F90 +shared/time_manager/time_manager.F90 +shared/tracer_manager/tracer_manager.F90 +atmos_shared/interpolator/interpolator.F90 +shared/horiz_interp/horiz_interp_bicubic.F90 +shared/horiz_interp/horiz_interp_bilinear.F90 +shared/horiz_interp/horiz_interp_conserve.F90 +shared/horiz_interp/horiz_interp.F90 +shared/horiz_interp/horiz_interp_spherical.F90 +shared/horiz_interp/horiz_interp_type.F90 +shared/time_interp/time_interp_external.F90 +shared/time_interp/time_interp.F90 +shared/axis_utils/axis_utils.F90 diff --git a/src/extra/model/socrates/path_names b/src/extra/model/socrates/path_names index 6cb698ede..59dc4cc24 100644 --- a/src/extra/model/socrates/path_names +++ b/src/extra/model/socrates/path_names @@ -11,6 +11,12 @@ atmos_param/sea_esf_rad/null/rad_utilities.F90 atmos_param/shallow_conv/shallow_conv.F90 atmos_param/stable_bl_turb/stable_bl_turb.F90 atmos_param/strat_cloud/null/strat_cloud.F90 +atmos_param/cloud_simple/cloud_simple.F90 +atmos_param/cloud_simple/lcl.F90 +atmos_param/cloud_simple/large_scale_cloud.F90 +atmos_param/cloud_simple/marine_strat_cloud.F90 +atmos_param/cloud_simple/cloud_cover_diags.F90 +atmos_param/cloud_simple/cloud_spookie.F90 atmos_param/two_stream_gray_rad/two_stream_gray_rad.F90 atmos_param/qflux/qflux.f90 atmos_param/monin_obukhov/monin_obukhov_interfaces.h @@ -328,89 +334,6 @@ atmos_param/socrates/src/trunk/src/radiance_core/monochromatic_radiance.F90 atmos_param/socrates/src/trunk/src/radiance_core/aggregate_cloud.F90 atmos_param/socrates/src/trunk/src/radiance_core/radiance_calc.F90 atmos_param/socrates/src/trunk/src/radiance_core/ir_source.F90 -atmos_param/socrates/src/trunk/src/scatter/conjugate_gradient_cloud_90.f90 -atmos_param/socrates/src/trunk/src/scatter/method_weight_pcf.f90 -atmos_param/socrates/src/trunk/src/scatter/select_weight_scatter_90.f90 -atmos_param/socrates/src/trunk/src/scatter/measure_particle_pcf.f90 -atmos_param/socrates/src/trunk/src/scatter/prec_integral_tcf.f90 -atmos_param/socrates/src/trunk/src/scatter/def_s_scat_prop.f90 -atmos_param/socrates/src/trunk/src/scatter/db_scatter_integral.f90 -atmos_param/socrates/src/trunk/src/scatter/weightings_90.f90 -atmos_param/socrates/src/trunk/src/scatter/def_db_ss_mono.f90 -atmos_param/socrates/src/trunk/src/scatter/cloud_fitting.f90 -atmos_param/socrates/src/trunk/src/scatter/shape_particle_pcf.f90 -atmos_param/socrates/src/trunk/src/scatter/number_particle_90.f90 -atmos_param/socrates/src/trunk/src/scatter/db_interp_ss_mono.f90 -atmos_param/socrates/src/trunk/src/scatter/db_read_single_wavelength.f90 -atmos_param/socrates/src/trunk/src/scatter/get_refract_index.f90 -atmos_param/socrates/src/trunk/src/scatter/read_scatter_block_90.f90 -atmos_param/socrates/src/trunk/src/scatter/proj_area_particle.f90 -atmos_param/socrates/src/trunk/src/scatter/line_search_cloud_90.f90 -atmos_param/socrates/src/trunk/src/scatter/volume_particle.f90 -atmos_param/socrates/src/trunk/src/scatter/distribution_pcf.f90 -atmos_param/socrates/src/trunk/src/scatter/size_integral_90.f90 -atmos_param/socrates/src/trunk/src/scatter/particle_size_90.f90 -atmos_param/socrates/src/trunk/src/scatter/max_size_acf.f90 -atmos_param/socrates/src/trunk/src/scatter/write_average_90.f90 -atmos_param/socrates/src/trunk/src/scatter/adt_mitchell96.f90 -atmos_param/socrates/src/trunk/src/scatter/get_db_wavelengths.f90 -atmos_param/socrates/src/trunk/src/scatter/decompose_phf_90.f90 -atmos_param/socrates/src/trunk/src/scatter/cloud_fit_parm_acf.f90 -atmos_param/socrates/src/trunk/src/scatter/cloud_fit_90.f90 -atmos_param/socrates/src/trunk/src/scatter/ice_db_read_geometry.f90 -atmos_param/socrates/src/trunk/src/scatter/def_sct_db.f90 -atmos_param/socrates/src/trunk/src/scatter/open_average_90.f90 -atmos_param/socrates/src/trunk/src/scatter/def_size_dist.f90 -atmos_param/socrates/src/trunk/src/scatter/parm_integ_acf.f90 -atmos_param/socrates/src/trunk/src/scatter/bna_factor_ccf.f90 -atmos_param/socrates/src/trunk/src/scatter/def_db_crystal_geometry.f90 -atmos_param/socrates/src/trunk/src/scatter/get_wavelengths.f90 -atmos_param/socrates/src/trunk/src/scatter/weightings_single_90.f90 -atmos_param/socrates/src/trunk/src/scatter/scatter_algorithm_pcf.f90 -atmos_param/socrates/src/trunk/src/scatter/db_type_ucf.f90 -atmos_param/socrates/src/trunk/src/scatter/scatter_integral_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/voigt_profile.f90 -atmos_param/socrates/src/trunk/src/correlated_k/adjust_path.f90 -atmos_param/socrates/src/trunk/src/correlated_k/func_scale_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/read_pt_line_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/set_condition_ck_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/caviar_continuum_v1_0.f90 -atmos_param/socrates/src/trunk/src/correlated_k/rad_weight_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/select_weight_ck_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/trans_k_dist.f90 -atmos_param/socrates/src/trunk/src/correlated_k/type_residual_pcf.f90 -atmos_param/socrates/src/trunk/src/correlated_k/map_shell.f90 -atmos_param/socrates/src/trunk/src/correlated_k/terminate_scale_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/ckd_continuum_v2_4.f90 -atmos_param/socrates/src/trunk/src/correlated_k/write_fit_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/ck_parm_acf.f90 -atmos_param/socrates/src/trunk/src/correlated_k/fit_parabola_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/func_scale_derivative_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/optimal_k.f90 -atmos_param/socrates/src/trunk/src/correlated_k/open_file_out_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/residual_gradient_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/scale_ck_fit_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/read_ref_pt_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/corr_k_single.f90 -atmos_param/socrates/src/trunk/src/correlated_k/planck_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/exponent_fit_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/conjugate_gradient_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/line_prof_corr_mod.f90 -atmos_param/socrates/src/trunk/src/correlated_k/set_extern_ckd_frn_data.f90 -atmos_param/socrates/src/trunk/src/correlated_k/set_g_point_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/bi_interp.f90 -atmos_param/socrates/src/trunk/src/correlated_k/residual_trans_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/set_extern_ckd_self_data.f90 -atmos_param/socrates/src/trunk/src/correlated_k/line_search_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/read_hitran.f90 -atmos_param/socrates/src/trunk/src/correlated_k/read_nc.f90 -atmos_param/socrates/src/trunk/src/correlated_k/ckd_extern_data.f90 -atmos_param/socrates/src/trunk/src/correlated_k/def_hitran_record.f90 -atmos_param/socrates/src/trunk/src/correlated_k/d_planck_90.f90 -atmos_param/socrates/src/trunk/src/correlated_k/scale_parameters_acf.f90 -atmos_param/socrates/src/trunk/src/correlated_k/offset_residual_trans_acf.f90 -atmos_param/socrates/src/trunk/src/correlated_k/hitran_cnst.f90 -atmos_param/socrates/src/trunk/src/correlated_k/ck_fit_pcf.f90 atmos_param/socrates/src/trunk/src/aux/qsat_wat.F90 atmos_param/socrates/src/trunk/src/aux/qsat_gill.F90 atmos_param/socrates/src/trunk/src/aux/write_cdf.f90 @@ -433,7 +356,6 @@ atmos_param/socrates/src/trunk/src/general/make_block_18.f90 atmos_param/socrates/src/trunk/src/general/remove_negative_gas_90.f90 atmos_param/socrates/src/trunk/src/general/make_block_17.f90 atmos_param/socrates/src/trunk/src/general/make_block_1.f90 -atmos_param/socrates/src/trunk/src/general/solar_intensity_90.f90 atmos_param/socrates/src/trunk/src/general/make_block_19.f90 atmos_param/socrates/src/trunk/src/general/make_block_0.f90 atmos_param/socrates/src/trunk/src/general/make_block_10.f90 @@ -483,8 +405,6 @@ atmos_param/socrates/src/trunk/src/radiation_control/set_moist_aerosol_propertie atmos_param/socrates/src/trunk/src/radiation_control/mcica_mod.F90 atmos_param/socrates/src/trunk/src/radiation_control/cld_generator_mod.F90 atmos_param/socrates/src/trunk/src/radiation_control/open_cloud_gen.F90 -atmos_param/socrates/src/trunk/src/um/out_nml.f90 -atmos_param/socrates/src/trunk/src/um/def_um_nml.f90 atmos_param/socrates/src/trunk/src/modules_core/errormessagelength_mod.F90 atmos_param/socrates/src/trunk/src/modules_core/dimensions_spec_ucf.F90 atmos_param/socrates/src/trunk/src/modules_core/rad_ccf.F90 @@ -496,11 +416,6 @@ atmos_param/socrates/src/trunk/src/modules_core/vectlib_mod.F90 atmos_param/socrates/src/trunk/src/modules_core/ereport_mod.F90 atmos_param/socrates/src/trunk/src/modules_core/realtype_rd.f90 atmos_param/socrates/src/trunk/src/modules_core/filenamelength_mod.F90 -atmos_param/socrates/src/trunk/src/scatter/grow_particles.f -atmos_param/socrates/src/trunk/src/scatter/mie_scatter.f -atmos_param/socrates/src/trunk/src/scatter/adt_integral.f -atmos_param/socrates/src/trunk/src/scatter/gamma_fnc.f -atmos_param/socrates/src/trunk/src/scatter/refractive_index.f atmos_param/socrates/src/trunk/src/aux/output_vert_cdl.f atmos_param/socrates/src/trunk/src/aux/assign_input_opt_cdf.f atmos_param/socrates/src/trunk/src/aux/assign_input_ss_cdl.f @@ -583,6 +498,7 @@ atmos_param/socrates/src/trunk/src/general/read_word.f atmos_param/socrates/interface/read_control.F90 atmos_param/socrates/interface/set_atm.F90 atmos_param/socrates/interface/set_cld.F90 +atmos_param/socrates/interface/socrates_set_cld.F90 atmos_param/socrates/interface/set_dimen.F90 atmos_param/socrates/interface/socrates_config_mod.f90 atmos_param/socrates/interface/compress_spectrum.F90 diff --git a/src/extra/model/socrates_column/field_table b/src/extra/model/socrates_column/field_table new file mode 100644 index 000000000..c2d63b9dd --- /dev/null +++ b/src/extra/model/socrates_column/field_table @@ -0,0 +1,10 @@ + +"TRACER", "atmos_mod", "sphum" + "longname", "specific humidity" + "units", "kg/kg" + "numerical_representation", "grid" + "hole_filling", "off" + "advect_vert", "finite_volume_parabolic" + "robert_filter", "on" + "profile_type", "fixed", "surface_value=0.0" / + diff --git a/src/extra/model/socrates_column/path_names b/src/extra/model/socrates_column/path_names new file mode 100644 index 000000000..92c7dbe95 --- /dev/null +++ b/src/extra/model/socrates_column/path_names @@ -0,0 +1,584 @@ +atmos_column/column.F90 +atmos_column/column_init_cond.F90 +atmos_column/column_grid.F90 +atmos_column/column_initialize_fields.F90 +atmos_param/diffusivity/diffusivity.F90 +atmos_param/edt/edt.F90 +atmos_param/entrain/entrain.F90 +atmos_param/hs_forcing/hs_forcing.F90 +atmos_param/lscale_cond/lscale_cond.F90 +atmos_param/my25_turb/my25_turb.F90 +atmos_param/qe_moist_convection/qe_moist_convection.F90 +atmos_param/betts_miller/betts_miller.f90 +atmos_param/ras/ras.f90 +atmos_param/sea_esf_rad/null/rad_utilities.F90 +atmos_param/shallow_conv/shallow_conv.F90 +atmos_param/stable_bl_turb/stable_bl_turb.F90 +atmos_param/strat_cloud/null/strat_cloud.F90 +atmos_param/cloud_simple/cloud_simple.F90 +atmos_param/cloud_simple/lcl.F90 +atmos_param/cloud_simple/large_scale_cloud.F90 +atmos_param/cloud_simple/marine_strat_cloud.F90 +atmos_param/cloud_simple/cloud_cover_diags.F90 +atmos_param/cloud_simple/cloud_spookie.F90 +atmos_param/two_stream_gray_rad/two_stream_gray_rad.F90 +atmos_param/qflux/qflux.f90 +atmos_param/monin_obukhov/monin_obukhov_interfaces.h +atmos_param/monin_obukhov/monin_obukhov_kernel.F90 +atmos_param/monin_obukhov/monin_obukhov.F90 +atmos_param/dry_convection/dry_convection.f90 +atmos_param/rayleigh_bottom_drag/rayleigh_bottom_drag.F90 +atmos_param/damping_driver/damping_driver.f90 +atmos_param/mg_drag/mg_drag.f90 +atmos_param/cg_drag/cg_drag.f90 +atmos_param/topo_drag/topo_drag.f90 +atmos_param/vert_diff/vert_diff.F90 +atmos_param/vert_turb_driver/vert_turb_driver.F90 +atmos_shared/interpolator/interpolator.F90 +atmos_shared/vert_advection/vert_advection.F90 +atmos_solo/atmos_model.F90 +atmos_spectral/driver/solo/atmosphere.F90 +atmos_spectral/driver/solo/idealized_moist_phys.F90 +atmos_spectral/driver/solo/mixed_layer.F90 +atmos_spectral/init/vert_coordinate.F90 +atmos_spectral/model/press_and_geopot.F90 +atmos_spectral/model/tracer_type.F90 +atmos_spectral/tools/spec_mpp.F90 +coupler/surface_flux.F90 +shared/axis_utils/axis_utils.F90 +shared/constants/constants.F90 +shared/astronomy/astronomy.f90 +shared/diag_manager/diag_axis.F90 +shared/diag_manager/diag_data.F90 +shared/diag_manager/diag_grid.F90 +shared/diag_manager/diag_manager.F90 +shared/diag_manager/diag_output.F90 +shared/diag_manager/diag_table.F90 +shared/diag_manager/diag_util.F90 +shared/fft/fft99.F90 +shared/fft/fft.F90 +shared/field_manager/field_manager.F90 +shared/field_manager/fm_util.F90 +shared/field_manager/parse.inc +shared/fms/fms.F90 +shared/fms/fms_io.F90 +shared/fms/read_data_2d.inc +shared/fms/read_data_3d.inc +shared/fms/read_data_4d.inc +shared/fms/test_fms_io.F90 +shared/fms/write_data.inc +shared/horiz_interp/horiz_interp_bicubic.F90 +shared/horiz_interp/horiz_interp_bilinear.F90 +shared/horiz_interp/horiz_interp_conserve.F90 +shared/horiz_interp/horiz_interp.F90 +shared/horiz_interp/horiz_interp_spherical.F90 +shared/horiz_interp/horiz_interp_type.F90 +shared/include/fms_platform.h +shared/memutils/memuse.c +shared/memutils/memutils.F90 +shared/mosaic/constant.h +shared/mosaic/create_xgrid.c +shared/mosaic/create_xgrid.h +shared/mosaic/gradient_c2l.c +shared/mosaic/gradient_c2l.h +shared/mosaic/gradient.F90 +shared/mosaic/grid.F90 +shared/mosaic/interp.c +shared/mosaic/interp.h +shared/mosaic/mosaic.F90 +shared/mosaic/mosaic_util.c +shared/mosaic/mosaic_util.h +shared/mosaic/read_mosaic.c +shared/mosaic/read_mosaic.h +shared/mpp/affinity.c +shared/mpp/include/mpp_chksum.h +shared/mpp/include/mpp_chksum_int.h +shared/mpp/include/mpp_chksum_scalar.h +shared/mpp/include/mpp_comm.inc +shared/mpp/include/mpp_comm_mpi.inc +shared/mpp/include/mpp_comm_nocomm.inc +shared/mpp/include/mpp_comm_sma.inc +shared/mpp/include/mpp_data_mpi.inc +shared/mpp/include/mpp_data_nocomm.inc +shared/mpp/include/mpp_data_sma.inc +shared/mpp/include/mpp_define_nest_domains.inc +shared/mpp/include/mpp_do_check.h +shared/mpp/include/mpp_do_checkV.h +shared/mpp/include/mpp_do_get_boundary.h +shared/mpp/include/mpp_do_global_field.h +shared/mpp/include/mpp_domains_comm.inc +shared/mpp/include/mpp_domains_define.inc +shared/mpp/include/mpp_domains_misc.inc +shared/mpp/include/mpp_domains_reduce.inc +shared/mpp/include/mpp_domains_util.inc +shared/mpp/include/mpp_do_redistribute.h +shared/mpp/include/mpp_do_update_ad.h +shared/mpp/include/mpp_do_update.h +shared/mpp/include/mpp_do_update_nest.h +shared/mpp/include/mpp_do_update_nonblock.h +shared/mpp/include/mpp_do_updateV_ad.h +shared/mpp/include/mpp_do_updateV.h +shared/mpp/include/mpp_do_updateV_nonblock.h +shared/mpp/include/mpp_error_a_a.h +shared/mpp/include/mpp_error_a_s.h +shared/mpp/include/mpp_error_s_a.h +shared/mpp/include/mpp_error_s_s.h +shared/mpp/include/mpp_gather.h +shared/mpp/include/mpp_get_boundary.h +shared/mpp/include/mpp_global_field.h +shared/mpp/include/mpp_global_reduce.h +shared/mpp/include/mpp_global_sum_ad.h +shared/mpp/include/mpp_global_sum.h +shared/mpp/include/mpp_global_sum_tl.h +shared/mpp/include/mpp_io_connect.inc +shared/mpp/include/mpp_io_misc.inc +shared/mpp/include/mpp_io_read.inc +shared/mpp/include/mpp_io_util.inc +shared/mpp/include/mpp_io_write.inc +shared/mpp/include/mpp_read_2Ddecomp.h +shared/mpp/include/mpp_reduce_mpi.h +shared/mpp/include/mpp_reduce_nocomm.h +shared/mpp/include/mpp_reduce_sma.h +shared/mpp/include/mpp_sum.inc +shared/mpp/include/mpp_sum_mpi.h +shared/mpp/include/mpp_sum_nocomm.h +shared/mpp/include/mpp_sum_sma.h +shared/mpp/include/mpp_transmit.inc +shared/mpp/include/mpp_transmit_mpi.h +shared/mpp/include/mpp_transmit_nocomm.h +shared/mpp/include/mpp_transmit_sma.h +shared/mpp/include/mpp_update_domains2D_ad.h +shared/mpp/include/mpp_update_domains2D.h +shared/mpp/include/mpp_update_domains2D_nonblock.h +shared/mpp/include/mpp_update_nest_domains.h +shared/mpp/include/mpp_util.inc +shared/mpp/include/mpp_util_mpi.inc +shared/mpp/include/mpp_util_nocomm.inc +shared/mpp/include/mpp_util_sma.inc +shared/mpp/include/mpp_write_2Ddecomp.h +shared/mpp/include/mpp_write.h +shared/mpp/include/system_clock.h +shared/mpp/mpp_data.F90 +shared/mpp/mpp_domains.F90 +shared/mpp/mpp.F90 +shared/mpp/mpp_io.F90 +shared/mpp/mpp_memutils.F90 +shared/mpp/mpp_parameter.F90 +shared/mpp/mpp_pset.F90 +shared/mpp/mpp_utilities.F90 +shared/mpp/nsclock.c +shared/mpp/test_mpp_domains.F90 +shared/mpp/test_mpp.F90 +shared/mpp/test_mpp_io.F90 +shared/mpp/test_mpp_pset.F90 +shared/mpp/threadloc.c +shared/platform/platform.F90 +shared/random_numbers/MersenneTwister.F90 +shared/random_numbers/random_numbers.F90 +shared/sat_vapor_pres/sat_vapor_pres.F90 +shared/sat_vapor_pres/sat_vapor_pres_k.F90 +shared/time_interp/time_interp_external.F90 +shared/time_interp/time_interp.F90 +shared/time_manager/get_cal_time.F90 +shared/time_manager/time_manager.F90 +shared/topography/gaussian_topog.F90 +shared/topography/topography.F90 +shared/tracer_manager/tracer_manager.F90 +shared/tridiagonal/tridiagonal.F90 +atmos_param/socrates/src/trunk/src/aux/cdf_struc.finc +atmos_param/socrates/src/trunk/src/aux/cdl_struc.finc +atmos_param/socrates/src/trunk/src/aux/dec_disort.finc +atmos_param/socrates/src/trunk/src/aux/call_disort.finc +atmos_param/socrates/src/trunk/src/general/batch_error_main.finc +atmos_param/socrates/src/trunk/src/general/aerosol_component.finc +atmos_param/socrates/src/trunk/src/radiance_core/gauss_angle.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solver_mix_direct.F90 +atmos_param/socrates/src/trunk/src/radiance_core/set_dirn_weights.F90 +atmos_param/socrates/src/trunk/src/radiance_core/calc_brdf.F90 +atmos_param/socrates/src/trunk/src/radiance_core/triple_solar_source.F90 +atmos_param/socrates/src/trunk/src/radiance_core/eval_uplm.F90 +atmos_param/socrates/src/trunk/src/radiance_core/shell_sort.F90 +atmos_param/socrates/src/trunk/src/radiance_core/rad_pcf.F90 +atmos_param/socrates/src/trunk/src/radiance_core/check_phf_term.F90 +atmos_param/socrates/src/trunk/src/radiance_core/set_n_source_coeff.F90 +atmos_param/socrates/src/trunk/src/radiance_core/calc_surf_rad.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solve_band_random_overlap.F90 +atmos_param/socrates/src/trunk/src/radiance_core/scale_absorb.F90 +atmos_param/socrates/src/trunk/src/radiance_core/calculate_density.F90 +atmos_param/socrates/src/trunk/src/radiance_core/calc_flux_ipa.F90 +atmos_param/socrates/src/trunk/src/radiance_core/opt_prop_ice_cloud.F90 +atmos_param/socrates/src/trunk/src/radiance_core/diff_planck_source_tbl.F90 +atmos_param/socrates/src/trunk/src/radiance_core/eig_sys.F90 +atmos_param/socrates/src/trunk/src/radiance_core/adjust_ir_radiance.F90 +atmos_param/socrates/src/trunk/src/radiance_core/set_rad_layer.F90 +atmos_param/socrates/src/trunk/src/radiance_core/def_dimen.F90 +atmos_param/socrates/src/trunk/src/radiance_core/mcica_column.F90 +atmos_param/socrates/src/trunk/src/radiance_core/interp1d.F90 +atmos_param/socrates/src/trunk/src/radiance_core/calc_uplm_zero.F90 +atmos_param/socrates/src/trunk/src/radiance_core/spline_fit.F90 +atmos_param/socrates/src/trunk/src/radiance_core/gaussian_weight_pcf.F90 +atmos_param/socrates/src/trunk/src/radiance_core/gas_list_pcf.F90 +atmos_param/socrates/src/trunk/src/radiance_core/trans_source_coeff.F90 +atmos_param/socrates/src/trunk/src/radiance_core/band_solver.F90 +atmos_param/socrates/src/trunk/src/radiance_core/mcica_sample.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solver_mix_direct_hogan.F90 +atmos_param/socrates/src/trunk/src/radiance_core/calc_uplm_sol.F90 +atmos_param/socrates/src/trunk/src/radiance_core/sph_matrix_solver.F90 +atmos_param/socrates/src/trunk/src/radiance_core/def_spectrum.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solver_triple_app_scat.F90 +atmos_param/socrates/src/trunk/src/radiance_core/grey_opt_prop.F90 +atmos_param/socrates/src/trunk/src/radiance_core/calc_gauss_weight_90.F90 +atmos_param/socrates/src/trunk/src/radiance_core/sum_k.F90 +atmos_param/socrates/src/trunk/src/radiance_core/ses_rescale_contm.F90 +atmos_param/socrates/src/trunk/src/radiance_core/spline_evaluate.F90 +atmos_param/socrates/src/trunk/src/radiance_core/cg_kappa_ms.F90 +atmos_param/socrates/src/trunk/src/radiance_core/def_bound.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solve_band_random_overlap_resort_rebin.F90 +atmos_param/socrates/src/trunk/src/radiance_core/monochromatic_gas_flux.F90 +atmos_param/socrates/src/trunk/src/radiance_core/set_cloud_pointer.F90 +atmos_param/socrates/src/trunk/src/radiance_core/set_cloud_geometry.F90 +atmos_param/socrates/src/trunk/src/radiance_core/rescale_phase_fnc.F90 +atmos_param/socrates/src/trunk/src/radiance_core/monochromatic_radiance_sph.F90 +atmos_param/socrates/src/trunk/src/radiance_core/inter_k.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solve_band_one_gas.F90 +atmos_param/socrates/src/trunk/src/radiance_core/calc_top_rad.F90 +atmos_param/socrates/src/trunk/src/radiance_core/set_n_cloud_parameter.F90 +atmos_param/socrates/src/trunk/src/radiance_core/set_level_weights.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solve_band_k_eqv_scl.F90 +atmos_param/socrates/src/trunk/src/radiance_core/set_matrix_pentadiagonal.F90 +atmos_param/socrates/src/trunk/src/radiance_core/mix_app_scat.F90 +atmos_param/socrates/src/trunk/src/radiance_core/def_out.F90 +atmos_param/socrates/src/trunk/src/radiance_core/sol_scat_cos.F90 +atmos_param/socrates/src/trunk/src/radiance_core/copy_clr_full.F90 +atmos_param/socrates/src/trunk/src/radiance_core/eigenvalue_tri.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solver_homogen_direct.F90 +atmos_param/socrates/src/trunk/src/radiance_core/rescale_continuum.F90 +atmos_param/socrates/src/trunk/src/radiance_core/mixed_solar_source.F90 +atmos_param/socrates/src/trunk/src/radiance_core/def_aer.F90 +atmos_param/socrates/src/trunk/src/radiance_core/opt_prop_inhom_corr_cairns.F90 +atmos_param/socrates/src/trunk/src/radiance_core/rebin_esft_terms.F90 +atmos_param/socrates/src/trunk/src/radiance_core/mix_column.F90 +atmos_param/socrates/src/trunk/src/radiance_core/prsc_gather_spline.F90 +atmos_param/socrates/src/trunk/src/radiance_core/calc_cg_coeff.F90 +atmos_param/socrates/src/trunk/src/radiance_core/inter_pt_lookup.F90 +atmos_param/socrates/src/trunk/src/radiance_core/opt_prop_ukca_aerosol.F90 +atmos_param/socrates/src/trunk/src/radiance_core/scale_wenyi.F90 +atmos_param/socrates/src/trunk/src/radiance_core/triple_column.F90 +atmos_param/socrates/src/trunk/src/radiance_core/single_scattering_all.F90 +atmos_param/socrates/src/trunk/src/radiance_core/inter_pt.F90 +atmos_param/socrates/src/trunk/src/radiance_core/overlap_coupled.F90 +atmos_param/socrates/src/trunk/src/radiance_core/def_cld.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solar_coefficient_basic.F90 +atmos_param/socrates/src/trunk/src/radiance_core/build_sph_matrix.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solve_band_k_eqv.F90 +atmos_param/socrates/src/trunk/src/radiance_core/augment_tiled_radiance.F90 +atmos_param/socrates/src/trunk/src/radiance_core/column_solver.F90 +atmos_param/socrates/src/trunk/src/radiance_core/augment_radiance.F90 +atmos_param/socrates/src/trunk/src/radiance_core/def_control.F90 +atmos_param/socrates/src/trunk/src/radiance_core/two_coeff_basic.F90 +atmos_param/socrates/src/trunk/src/radiance_core/sph_solver.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solver_no_scat.F90 +atmos_param/socrates/src/trunk/src/radiance_core/copy_clr_sol.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solar_source.F90 +atmos_param/socrates/src/trunk/src/radiance_core/opt_prop_water_cloud.F90 +atmos_param/socrates/src/trunk/src/radiance_core/legendre_weight.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solve_band_without_gas.F90 +atmos_param/socrates/src/trunk/src/radiance_core/diff_albedo_basis.F90 +atmos_param/socrates/src/trunk/src/radiance_core/increment_rad_cf.F90 +atmos_param/socrates/src/trunk/src/radiance_core/single_scat_sol.F90 +atmos_param/socrates/src/trunk/src/radiance_core/opt_prop_aerosol.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solve_band_ses.F90 +atmos_param/socrates/src/trunk/src/radiance_core/def_ss_prop.F90 +atmos_param/socrates/src/trunk/src/radiance_core/prsc_opt_prop.F90 +atmos_param/socrates/src/trunk/src/radiance_core/layer_part_integ.F90 +atmos_param/socrates/src/trunk/src/radiance_core/two_coeff_fast_lw.F90 +atmos_param/socrates/src/trunk/src/radiance_core/gas_optical_properties.F90 +atmos_param/socrates/src/trunk/src/radiance_core/single_scattering.F90 +atmos_param/socrates/src/trunk/src/radiance_core/monochromatic_ir_radiance.F90 +atmos_param/socrates/src/trunk/src/radiance_core/hemi_sph_integ.F90 +atmos_param/socrates/src/trunk/src/radiance_core/two_coeff_cloud.F90 +atmos_param/socrates/src/trunk/src/radiance_core/read_spectrum.F90 +atmos_param/socrates/src/trunk/src/radiance_core/inter_t_lookup.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solver_triple.F90 +atmos_param/socrates/src/trunk/src/radiance_core/two_stream.F90 +atmos_param/socrates/src/trunk/src/radiance_core/solver_triple_hogan.F90 +atmos_param/socrates/src/trunk/src/radiance_core/monochromatic_radiance_tseq.F90 +atmos_param/socrates/src/trunk/src/radiance_core/cloud_maxcs_split.F90 +atmos_param/socrates/src/trunk/src/radiance_core/def_atm.F90 +atmos_param/socrates/src/trunk/src/radiance_core/two_coeff.F90 +atmos_param/socrates/src/trunk/src/radiance_core/two_coeff_region.F90 +atmos_param/socrates/src/trunk/src/radiance_core/quicksort.F90 +atmos_param/socrates/src/trunk/src/radiance_core/rescale_tau_omega.F90 +atmos_param/socrates/src/trunk/src/radiance_core/calc_radiance_ipa.F90 +atmos_param/socrates/src/trunk/src/radiance_core/two_coeff_region_fast_lw.F90 +atmos_param/socrates/src/trunk/src/radiance_core/diff_planck_source_poly.F90 +atmos_param/socrates/src/trunk/src/radiance_core/set_truncation.F90 +atmos_param/socrates/src/trunk/src/radiance_core/monochromatic_radiance.F90 +atmos_param/socrates/src/trunk/src/radiance_core/aggregate_cloud.F90 +atmos_param/socrates/src/trunk/src/radiance_core/radiance_calc.F90 +atmos_param/socrates/src/trunk/src/radiance_core/ir_source.F90 +atmos_param/socrates/src/trunk/src/scatter/conjugate_gradient_cloud_90.f90 +atmos_param/socrates/src/trunk/src/scatter/method_weight_pcf.f90 +atmos_param/socrates/src/trunk/src/scatter/select_weight_scatter_90.f90 +atmos_param/socrates/src/trunk/src/scatter/measure_particle_pcf.f90 +atmos_param/socrates/src/trunk/src/scatter/prec_integral_tcf.f90 +atmos_param/socrates/src/trunk/src/scatter/def_s_scat_prop.f90 +atmos_param/socrates/src/trunk/src/scatter/db_scatter_integral.f90 +atmos_param/socrates/src/trunk/src/scatter/weightings_90.f90 +atmos_param/socrates/src/trunk/src/scatter/def_db_ss_mono.f90 +atmos_param/socrates/src/trunk/src/scatter/cloud_fitting.f90 +atmos_param/socrates/src/trunk/src/scatter/shape_particle_pcf.f90 +atmos_param/socrates/src/trunk/src/scatter/number_particle_90.f90 +atmos_param/socrates/src/trunk/src/scatter/db_interp_ss_mono.f90 +atmos_param/socrates/src/trunk/src/scatter/db_read_single_wavelength.f90 +atmos_param/socrates/src/trunk/src/scatter/get_refract_index.f90 +atmos_param/socrates/src/trunk/src/scatter/read_scatter_block_90.f90 +atmos_param/socrates/src/trunk/src/scatter/proj_area_particle.f90 +atmos_param/socrates/src/trunk/src/scatter/line_search_cloud_90.f90 +atmos_param/socrates/src/trunk/src/scatter/volume_particle.f90 +atmos_param/socrates/src/trunk/src/scatter/distribution_pcf.f90 +atmos_param/socrates/src/trunk/src/scatter/size_integral_90.f90 +atmos_param/socrates/src/trunk/src/scatter/particle_size_90.f90 +atmos_param/socrates/src/trunk/src/scatter/max_size_acf.f90 +atmos_param/socrates/src/trunk/src/scatter/write_average_90.f90 +atmos_param/socrates/src/trunk/src/scatter/adt_mitchell96.f90 +atmos_param/socrates/src/trunk/src/scatter/get_db_wavelengths.f90 +atmos_param/socrates/src/trunk/src/scatter/decompose_phf_90.f90 +atmos_param/socrates/src/trunk/src/scatter/cloud_fit_parm_acf.f90 +atmos_param/socrates/src/trunk/src/scatter/cloud_fit_90.f90 +atmos_param/socrates/src/trunk/src/scatter/ice_db_read_geometry.f90 +atmos_param/socrates/src/trunk/src/scatter/def_sct_db.f90 +atmos_param/socrates/src/trunk/src/scatter/open_average_90.f90 +atmos_param/socrates/src/trunk/src/scatter/def_size_dist.f90 +atmos_param/socrates/src/trunk/src/scatter/parm_integ_acf.f90 +atmos_param/socrates/src/trunk/src/scatter/bna_factor_ccf.f90 +atmos_param/socrates/src/trunk/src/scatter/def_db_crystal_geometry.f90 +atmos_param/socrates/src/trunk/src/scatter/get_wavelengths.f90 +atmos_param/socrates/src/trunk/src/scatter/weightings_single_90.f90 +atmos_param/socrates/src/trunk/src/scatter/scatter_algorithm_pcf.f90 +atmos_param/socrates/src/trunk/src/scatter/db_type_ucf.f90 +atmos_param/socrates/src/trunk/src/scatter/scatter_integral_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/voigt_profile.f90 +atmos_param/socrates/src/trunk/src/correlated_k/adjust_path.f90 +atmos_param/socrates/src/trunk/src/correlated_k/func_scale_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/read_pt_line_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/set_condition_ck_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/caviar_continuum_v1_0.f90 +atmos_param/socrates/src/trunk/src/correlated_k/rad_weight_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/select_weight_ck_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/trans_k_dist.f90 +atmos_param/socrates/src/trunk/src/correlated_k/type_residual_pcf.f90 +atmos_param/socrates/src/trunk/src/correlated_k/map_shell.f90 +atmos_param/socrates/src/trunk/src/correlated_k/terminate_scale_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/ckd_continuum_v2_4.f90 +atmos_param/socrates/src/trunk/src/correlated_k/write_fit_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/ck_parm_acf.f90 +atmos_param/socrates/src/trunk/src/correlated_k/fit_parabola_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/func_scale_derivative_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/optimal_k.f90 +atmos_param/socrates/src/trunk/src/correlated_k/open_file_out_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/residual_gradient_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/scale_ck_fit_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/read_ref_pt_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/corr_k_single.f90 +atmos_param/socrates/src/trunk/src/correlated_k/planck_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/exponent_fit_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/conjugate_gradient_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/line_prof_corr_mod.f90 +atmos_param/socrates/src/trunk/src/correlated_k/set_extern_ckd_frn_data.f90 +atmos_param/socrates/src/trunk/src/correlated_k/set_g_point_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/bi_interp.f90 +atmos_param/socrates/src/trunk/src/correlated_k/residual_trans_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/set_extern_ckd_self_data.f90 +atmos_param/socrates/src/trunk/src/correlated_k/line_search_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/read_hitran.f90 +atmos_param/socrates/src/trunk/src/correlated_k/read_nc.f90 +atmos_param/socrates/src/trunk/src/correlated_k/ckd_extern_data.f90 +atmos_param/socrates/src/trunk/src/correlated_k/def_hitran_record.f90 +atmos_param/socrates/src/trunk/src/correlated_k/d_planck_90.f90 +atmos_param/socrates/src/trunk/src/correlated_k/scale_parameters_acf.f90 +atmos_param/socrates/src/trunk/src/correlated_k/offset_residual_trans_acf.f90 +atmos_param/socrates/src/trunk/src/correlated_k/hitran_cnst.f90 +atmos_param/socrates/src/trunk/src/correlated_k/ck_fit_pcf.f90 +atmos_param/socrates/src/trunk/src/aux/qsat_wat.F90 +atmos_param/socrates/src/trunk/src/aux/qsat_gill.F90 +atmos_param/socrates/src/trunk/src/aux/write_cdf.f90 +atmos_param/socrates/src/trunk/src/aux/read_cdf.f90 +atmos_param/socrates/src/trunk/src/aux/aerosol_representation_pcf.f90 +atmos_param/socrates/src/trunk/src/aux/aerosol_profile_pcf.f90 +atmos_param/socrates/src/trunk/src/aux/write_samson.f90 +atmos_param/socrates/src/trunk/src/aux/filter_function.f90 +atmos_param/socrates/src/trunk/src/aux/qsat_alg_pcf.f90 +atmos_param/socrates/src/trunk/src/aux/method_merge_pcf.f90 +atmos_param/socrates/src/trunk/src/aux/rand_gauss.f90 +atmos_param/socrates/src/trunk/src/general/make_block_2_1.f90 +atmos_param/socrates/src/trunk/src/general/make_block_11.f90 +atmos_param/socrates/src/trunk/src/general/make_block_12.f90 +atmos_param/socrates/src/trunk/src/general/sum_unity.f90 +atmos_param/socrates/src/trunk/src/general/trapezoid_90.f90 +atmos_param/socrates/src/trunk/src/general/get_free_unit.F90 +atmos_param/socrates/src/trunk/src/general/rayleigh_scatter.f90 +atmos_param/socrates/src/trunk/src/general/make_block_18.f90 +atmos_param/socrates/src/trunk/src/general/remove_negative_gas_90.f90 +atmos_param/socrates/src/trunk/src/general/make_block_17.f90 +atmos_param/socrates/src/trunk/src/general/make_block_1.f90 +atmos_param/socrates/src/trunk/src/general/solar_intensity_90.f90 +atmos_param/socrates/src/trunk/src/general/make_block_19.f90 +atmos_param/socrates/src/trunk/src/general/make_block_0.f90 +atmos_param/socrates/src/trunk/src/general/make_block_10.f90 +atmos_param/socrates/src/trunk/src/general/make_block_14.f90 +atmos_param/socrates/src/trunk/src/general/read_solar_spectrum.f90 +atmos_param/socrates/src/trunk/src/general/remove_negative_cont_90.f90 +atmos_param/socrates/src/trunk/src/general/make_block_3_1.f90 +atmos_param/socrates/src/trunk/src/general/set_interactive.f90 +atmos_param/socrates/src/trunk/src/general/make_block_8.f90 +atmos_param/socrates/src/trunk/src/general/make_block_3.f90 +atmos_param/socrates/src/trunk/src/general/make_block_15.f90 +atmos_param/socrates/src/trunk/src/general/make_block_9.f90 +atmos_param/socrates/src/trunk/src/general/read_instrument_response_90.f90 +atmos_param/socrates/src/trunk/src/general/make_block_4.f90 +atmos_param/socrates/src/trunk/src/general/map_heap_func.f90 +atmos_param/socrates/src/trunk/src/general/make_block_6.f90 +atmos_param/socrates/src/trunk/src/general/out_spectrum.f90 +atmos_param/socrates/src/trunk/src/general/make_block_2.f90 +atmos_param/socrates/src/trunk/src/general/rayleigh_jeans_tail.f90 +atmos_param/socrates/src/trunk/src/general/solar_intensity.f90 +atmos_param/socrates/src/trunk/src/general/make_block_5.f90 +atmos_param/socrates/src/trunk/src/general/rayleigh_scatter_h2he.f90 +atmos_param/socrates/src/trunk/src/modules_gen/dimensions_field_cdf_ucf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/def_refract.f90 +atmos_param/socrates/src/trunk/src/modules_gen/scatter_pp_pcf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/def_std_io_icf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/dimensions_cdl_ucf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/refract_re_ccf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/def_inst_flt.f90 +atmos_param/socrates/src/trunk/src/modules_gen/dimensions_pp_ucf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/weighting_pcf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/error_pcf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/file_type_pcf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/def_data_in_icf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/dimensions_cdf_ucf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/unit_list_pcf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/realtypefx_rd.f90 +atmos_param/socrates/src/trunk/src/modules_gen/def_solarspec.f90 +atmos_param/socrates/src/trunk/src/modules_gen/interp_mode_pcf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/dimensions_fixed_pcf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/dimensions_field_ucf.f90 +atmos_param/socrates/src/trunk/src/modules_gen/input_head_pcf.f90 +atmos_param/socrates/src/trunk/src/radiation_control/close_cloud_gen.F90 +atmos_param/socrates/src/trunk/src/radiation_control/mcica_order.F90 +atmos_param/socrates/src/trunk/src/radiation_control/rand_no_mcica.F90 +atmos_param/socrates/src/trunk/src/radiation_control/set_moist_aerosol_properties.F90 +atmos_param/socrates/src/trunk/src/radiation_control/mcica_mod.F90 +atmos_param/socrates/src/trunk/src/radiation_control/cld_generator_mod.F90 +atmos_param/socrates/src/trunk/src/radiation_control/open_cloud_gen.F90 +atmos_param/socrates/src/trunk/src/um/out_nml.f90 +atmos_param/socrates/src/trunk/src/um/def_um_nml.f90 +atmos_param/socrates/src/trunk/src/modules_core/errormessagelength_mod.F90 +atmos_param/socrates/src/trunk/src/modules_core/dimensions_spec_ucf.F90 +atmos_param/socrates/src/trunk/src/modules_core/rad_ccf.F90 +atmos_param/socrates/src/trunk/src/modules_core/yomhook.F90 +atmos_param/socrates/src/trunk/src/modules_core/parkind1.F90 +atmos_param/socrates/src/trunk/src/modules_core/file_manager.F90 +atmos_param/socrates/src/trunk/src/modules_core/missing_data_mod.F90 +atmos_param/socrates/src/trunk/src/modules_core/vectlib_mod.F90 +atmos_param/socrates/src/trunk/src/modules_core/ereport_mod.F90 +atmos_param/socrates/src/trunk/src/modules_core/realtype_rd.f90 +atmos_param/socrates/src/trunk/src/modules_core/filenamelength_mod.F90 +atmos_param/socrates/src/trunk/src/scatter/grow_particles.f +atmos_param/socrates/src/trunk/src/scatter/mie_scatter.f +atmos_param/socrates/src/trunk/src/scatter/adt_integral.f +atmos_param/socrates/src/trunk/src/scatter/gamma_fnc.f +atmos_param/socrates/src/trunk/src/scatter/refractive_index.f +atmos_param/socrates/src/trunk/src/aux/output_vert_cdl.f +atmos_param/socrates/src/trunk/src/aux/assign_input_opt_cdf.f +atmos_param/socrates/src/trunk/src/aux/assign_input_ss_cdl.f +atmos_param/socrates/src/trunk/src/aux/split_cdl_line.f +atmos_param/socrates/src/trunk/src/aux/input_cloud_cdf.f +atmos_param/socrates/src/trunk/src/aux/assign_viewing_geom_cdl.f +atmos_param/socrates/src/trunk/src/aux/read_samson_p_field.f +atmos_param/socrates/src/trunk/src/aux/output_opt_profile_cdl.f +atmos_param/socrates/src/trunk/src/aux/input_cloud_cdl.f +atmos_param/socrates/src/trunk/src/aux/output_radiance_cdl.f +atmos_param/socrates/src/trunk/src/aux/fnc_density.f +atmos_param/socrates/src/trunk/src/aux/calc_volume_fraction.f +atmos_param/socrates/src/trunk/src/aux/calc_cdl_stride.f +atmos_param/socrates/src/trunk/src/aux/interp.f +atmos_param/socrates/src/trunk/src/aux/merge_pressure.f +atmos_param/socrates/src/trunk/src/aux/angular_control_cdf.f +atmos_param/socrates/src/trunk/src/aux/extinction_profile.f +atmos_param/socrates/src/trunk/src/aux/read_genln2_flux.f +atmos_param/socrates/src/trunk/src/aux/write_cdl.f +atmos_param/socrates/src/trunk/src/aux/find_var_cdl.f +atmos_param/socrates/src/trunk/src/aux/assign_input_vert_cdf.f +atmos_param/socrates/src/trunk/src/aux/input_aerosol_cdf.f +atmos_param/socrates/src/trunk/src/aux/assign_input_novert_cdl.f +atmos_param/socrates/src/trunk/src/aux/find_dimen_cdl.f +atmos_param/socrates/src/trunk/src/aux/output_flux_cdl.f +atmos_param/socrates/src/trunk/src/aux/assign_input_opt_cdl.f +atmos_param/socrates/src/trunk/src/aux/output_horiz_cdl.f +atmos_param/socrates/src/trunk/src/aux/seaalbedo_driver.f +atmos_param/socrates/src/trunk/src/aux/assign_viewing_geom_cdf.f +atmos_param/socrates/src/trunk/src/aux/angular_control.f +atmos_param/socrates/src/trunk/src/aux/output_vert_cdf.f +atmos_param/socrates/src/trunk/src/aux/output_view_cdl.f +atmos_param/socrates/src/trunk/src/aux/read_raw_profile.f +atmos_param/socrates/src/trunk/src/aux/qsat_gg_ice.f +atmos_param/socrates/src/trunk/src/aux/output_flux_cdf.f +atmos_param/socrates/src/trunk/src/aux/assign_surface_char_cdf.f +atmos_param/socrates/src/trunk/src/aux/name_length.f +atmos_param/socrates/src/trunk/src/aux/sort_raw_profile.f +atmos_param/socrates/src/trunk/src/aux/read_averaged_scatter.f +atmos_param/socrates/src/trunk/src/aux/write_cdl_field.f +atmos_param/socrates/src/trunk/src/aux/planck_ss_source.f +atmos_param/socrates/src/trunk/src/aux/output_photolysis_cdf.f +atmos_param/socrates/src/trunk/src/aux/output_radiance_cdf.f +atmos_param/socrates/src/trunk/src/aux/interpolate_p.f +atmos_param/socrates/src/trunk/src/aux/write_profile.f +atmos_param/socrates/src/trunk/src/aux/assign_surface_char_cdl.f +atmos_param/socrates/src/trunk/src/aux/planck_cumul.f +atmos_param/socrates/src/trunk/src/aux/input_aerosol_cdl.f +atmos_param/socrates/src/trunk/src/aux/assign_input_novert_cdf.f +atmos_param/socrates/src/trunk/src/aux/output_surf_cdl.f +atmos_param/socrates/src/trunk/src/aux/mono_rad_ss.f +atmos_param/socrates/src/trunk/src/aux/assign_horiz_cdl.f +atmos_param/socrates/src/trunk/src/aux/qsat.f +atmos_param/socrates/src/trunk/src/aux/set_state.f +atmos_param/socrates/src/trunk/src/aux/l_find_component.f +atmos_param/socrates/src/trunk/src/aux/qsat_gg.f +atmos_param/socrates/src/trunk/src/aux/read_cdl.f +atmos_param/socrates/src/trunk/src/aux/assign_input_vert_cdl.f +atmos_param/socrates/src/trunk/src/aux/output_photolysis_cdl.f +atmos_param/socrates/src/trunk/src/general/non_blank.f +atmos_param/socrates/src/trunk/src/general/remove_blank.f +atmos_param/socrates/src/trunk/src/general/simpsons_rule.f +atmos_param/socrates/src/trunk/src/general/point_bracket.f +atmos_param/socrates/src/trunk/src/general/trapezoid.f +atmos_param/socrates/src/trunk/src/general/planck.f +atmos_param/socrates/src/trunk/src/general/read_line.f +atmos_param/socrates/src/trunk/src/general/make_block_6_1.f +atmos_param/socrates/src/trunk/src/general/calc_thermal_coeff.f +atmos_param/socrates/src/trunk/src/general/open_file_out.f +atmos_param/socrates/src/trunk/src/general/back_substitute.f +atmos_param/socrates/src/trunk/src/general/open_file_in.f +atmos_param/socrates/src/trunk/src/general/integrate_spline.f +atmos_param/socrates/src/trunk/src/general/rayleigh_scatter_air.f +atmos_param/socrates/src/trunk/src/general/lock_code.f +atmos_param/socrates/src/trunk/src/general/make_block_6_2.f +atmos_param/socrates/src/trunk/src/general/inner_bracket.f +atmos_param/socrates/src/trunk/src/general/svd_decompose.f +atmos_param/socrates/src/trunk/src/general/calc_planck_tbl.f +atmos_param/socrates/src/trunk/src/general/read_word.f +atmos_param/socrates/interface/read_control.F90 +atmos_param/socrates/interface/set_atm.F90 +atmos_param/socrates/interface/set_cld.F90 +atmos_param/socrates/interface/socrates_set_cld.F90 +atmos_param/socrates/interface/set_dimen.F90 +atmos_param/socrates/interface/socrates_config_mod.f90 +atmos_param/socrates/interface/compress_spectrum.F90 +atmos_param/socrates/interface/set_aer.F90 +atmos_param/socrates/interface/set_bound.F90 +atmos_param/socrates/interface/set_control.F90 +atmos_param/socrates/interface/socrates_calc.F90 +atmos_param/socrates/interface/socrates_interface.F90 +atmos_param/socrates/interface/soc_constants.f90 diff --git a/src/extra/python/isca/__init__.py b/src/extra/python/isca/__init__.py index 5bf28c1a9..830b10774 100644 --- a/src/extra/python/isca/__init__.py +++ b/src/extra/python/isca/__init__.py @@ -83,4 +83,4 @@ def emit(self, event, *args, **kwargs): from isca.experiment import Experiment, DiagTable, Namelist, FailedRunError -from isca.codebase import IscaCodeBase, SocratesCodeBase, DryCodeBase, GreyCodeBase #, ShallowCodeBase +from isca.codebase import IscaCodeBase, SocratesCodeBase, DryCodeBase, GreyCodeBase, ShallowCodeBase, BarotropicCodeBase, ColumnCodeBase, SocColumnCodeBase diff --git a/src/extra/python/isca/codebase.py b/src/extra/python/isca/codebase.py index e6703813a..c411ff928 100644 --- a/src/extra/python/isca/codebase.py +++ b/src/extra/python/isca/codebase.py @@ -7,8 +7,9 @@ from isca import GFDL_WORK, GFDL_BASE, GFDL_SOC, _module_directory, get_env_file from .loghandler import Logger -from .helpers import url_to_folder, destructive, useworkdir, mkdir, cd, git, P, git_run_in_directory +from .helpers import url_to_folder, destructive, useworkdir, mkdir, git, P, git_run_in_directory, check_for_sh_stdout +import pdb class CodeBase(Logger): """The CodeBase. @@ -91,6 +92,28 @@ def __init__(self, repo=None, commit=None, directory=None, storedir=P(GFDL_WORK, self.checkout() else: self.link_source_to(directory) + elif self.code_is_available and self.commit is not None: + # problem is that if you try to checkout a specific commit, and it doesn't work, the next time you try it, the above code will only check if code exists, which it will, but it won't be at the correct commit. This will cause problems for e.g. the trip tests. Following code checks if the code that's checked out is the correct commit ID compared to what was asked for, and gives an error if they are different. + commit_at_HEAD_of_repo = self.git_commit.split('"')[1] + commit_desired = self.commit + if len(commit_desired)==len(commit_at_HEAD_of_repo): + commit_to_compare_1 = commit_desired + commit_to_compare_2 = commit_at_HEAD_of_repo + elif len(commit_desired)>len(commit_at_HEAD_of_repo): + commit_to_compare_1 = commit_desired[0:len(commit_at_HEAD_of_repo)] + commit_to_compare_2 = commit_at_HEAD_of_repo + else: + commit_to_compare_1 = commit_desired + commit_to_compare_2 = commit_at_HEAD_of_repo[0:len(commit_desired)] + + if commit_to_compare_1==commit_to_compare_2: + self.log.info('commit requested successfully checked out') + else: + self.log.warn('commit requested is not the commit to be used') + raise NotImplementedError("commit requested %s but commit supplied %s. This happens when you've previously tried to checkout a particular commit, but the commit was not found in the repo supplied. Try removing %s and trying again, making sure to select a repo that contains your desired commit." % (commit_to_compare_1, commit_to_compare_2, self.workdir )) + + + #TODO self.templates = Environment(loader=FileSystemLoader(self.templatedir)) @@ -114,7 +137,7 @@ def is_clean(self): @property def git_commit(self): - return self.git.log('-1', '--format="%H"').stdout.decode('utf8') + return check_for_sh_stdout(self.git.log('-1', '--format="%H"')) # @property # def git_diff(self): @@ -139,11 +162,12 @@ def write_source_control_status(self, outfile): # write out the git commit id of GFDL_BASE file.write("\n\n*---commit hash used for code in GFDL_BASE, including this python module---*:\n") - file.write(gfdl_git.log('-1', '--format="%H"').stdout.decode('utf8')) + gfdl_git_out = check_for_sh_stdout(gfdl_git.log('-1', '--format="%H"')) + file.write(gfdl_git_out) # if there are any uncommited changes in the working directory, # add those to the file too - source_status = self.git.status("-b", "--porcelain").stdout.decode('utf8') + source_status = check_for_sh_stdout(self.git.status("-b", "--porcelain")) # filter the source status for changes in specific files filetypes = ('.f90', '.inc', '.c') source_status = [line for line in source_status.split('\n') @@ -155,7 +179,7 @@ def write_source_control_status(self, outfile): file.write("*---git status output (only f90 and inc files)---*:\n") file.write('\n'.join(source_status)) file.write('\n\n*---git diff output---*\n') - source_diff = self.git.diff('--no-color').stdout.decode('utf8') + source_diff = check_for_sh_stdout(self.git.diff('--no-color')) file.write(source_diff) def read_path_names(self, path_names_file): @@ -324,6 +348,59 @@ def __init__(self, *args, **kwargs): self.disable_rrtm() self.simlink_to_soc_code() +class SocColumnCodeBase(CodeBase): + """Isca without RRTM but with the Met Office radiation scheme, Socrates. THIS VERSION FOR SINGLE COLUMN USE. + """ + #path_names_file = P(_module_directory, 'templates', 'moist_path_names') + name = 'socrates_column' + executable_name = 'soc_column_isca.x' + + def column_model(self): + self.compile_flags.append('-DCOLUMN_MODEL') + self.log.info('USING SINGLE COLUMN MODEL') + + def disable_rrtm(self): + # add no compile flag + self.compile_flags.append('-DRRTM_NO_COMPILE') + self.log.info('RRTM compilation disabled.') + + def simlink_to_soc_code(self): + #Make symlink to socrates source code if one doesn't already exist. + socrates_desired_location = self.codedir+'/src/atmos_param/socrates/src/trunk' + + #First check if socrates is in correct place already + if os.path.exists(socrates_desired_location): + link_correct = os.path.exists(socrates_desired_location+'/src/') + if link_correct: + socrates_code_in_desired_location=True + else: + socrates_code_in_desired_location=False + if os.path.islink(socrates_desired_location): + self.log.info('Socrates source code symlink is in correct place, but is to incorrect location. Trying to correct.') + os.unlink(socrates_desired_location) + else: + self.log.info('Socrates source code is in correct place, but folder structure is wrong. Contents of the folder '+socrates_desired_location+' should include a src folder.') + else: + socrates_code_in_desired_location=False + self.log.info('Socrates source code symlink does not exist. Creating.') + + # If socrates is not in the right place already, then attempt to make symlink to location of code provided by GFDL_SOC + if socrates_code_in_desired_location: + self.log.info('Socrates source code already in correct place. Continuing.') + else: + if GFDL_SOC is not None: + sh.ln('-s', GFDL_SOC, socrates_desired_location) + elif GFDL_SOC is None: + error_mesg = 'Socrates code is required for SocratesCodebase, but source code is not provided in location GFDL_SOC='+ str(GFDL_SOC) + self.log.error(error_mesg) + raise OSError(error_mesg) + + def __init__(self, *args, **kwargs): + super(SocColumnCodeBase, self).__init__(*args, **kwargs) + self.column_model() + self.disable_rrtm() + self.simlink_to_soc_code() + class GreyCodeBase(CodeBase): """The Frierson model. This is the closest to the Frierson model, with moist dynamics and a @@ -352,6 +429,27 @@ def __init__(self, *args, **kwargs): self.disable_rrtm() self.disable_soc() +class ColumnCodeBase(CodeBase): + """This contains code that will allow one to use all model physics in a single column configuration (i.e. without calling the dynamical core) + """ + #path_names_file = P(_module_directory, 'templates', 'moist_path_names') + name = 'column' + executable_name = 'column_isca.x' + + def column_model(self): + self.compile_flags.append('-DCOLUMN_MODEL') + self.log.info('USING SINGLE COLUMN MODEL') + + def disable_soc(self): + # add no compile flag + self.compile_flags.append('-DSOC_NO_COMPILE') + self.log.info('SOCRATES compilations diabled.') + + def __init__(self, *args, **kwargs): + super(ColumnCodeBase, self).__init__(*args, **kwargs) + self.column_model() + self.disable_soc() + class DryCodeBase(GreyCodeBase): """The Held-Suarez model. @@ -366,8 +464,14 @@ class DryCodeBase(GreyCodeBase): -# class ShallowCodeBase(CodeBase): -# """The Shallow Water Equations. -# """ -# name = 'shallow' -# executable_name = 'shallow.x' +class ShallowCodeBase(CodeBase): + """The Shallow Water Equations. + """ + name = 'shallow' + executable_name = 'shallow.x' + +class BarotropicCodeBase(CodeBase): + """The Barotropic vorticity equations. + """ + name = 'barotropic' + executable_name = 'barotropic_isca.x' \ No newline at end of file diff --git a/src/extra/python/isca/experiment.py b/src/extra/python/isca/experiment.py index b41a40668..9495bd178 100755 --- a/src/extra/python/isca/experiment.py +++ b/src/extra/python/isca/experiment.py @@ -47,7 +47,6 @@ class Experiment(Logger, EventEmitter): 'num_fourier': 42, 'num_spherical': 43, }, - 'T21': { 'lon_max': 64, 'lat_max': 32, @@ -144,6 +143,11 @@ def update_namelist(self, new_vals): def write_namelist(self, outdir): namelist_file = P(outdir, 'input.nml') self.log.info('Writing namelist to %r' % namelist_file) + # A fixed column width is added to be a fixed number as most string namelist variables are + # width 256 in Isca, so that width plus some indentation and the namelist parameters own + # name should not exceed 350 characters. Default f90nml value is 72, which is regularly + # too short for some namelist variables where directories are pointed to. + self.namelist.column_width = 350 self.namelist.write(namelist_file) def write_diag_table(self, outdir): diff --git a/src/extra/python/isca/helpers.py b/src/extra/python/isca/helpers.py index b1bc089d8..e17ce48e2 100644 --- a/src/extra/python/isca/helpers.py +++ b/src/extra/python/isca/helpers.py @@ -4,7 +4,7 @@ import sh mkdir = sh.mkdir.bake('-p') -cd = sh.cd +# cd = sh.cd git = sh.git.bake('--no-pager') P = os.path.join @@ -66,11 +66,19 @@ def git_run_in_directory(GFDL_BASE_DIR, dir_in): try: codedir_git = git.bake('-C', GFDL_BASE_DIR) - git_test = codedir_git.log('-1', '--format="%H"').stdout + git_test = check_for_sh_stdout(codedir_git.log('-1', '--format="%H"')) baked_git_fn = git.bake('-C', dir_in) except: codedir_git = git.bake('--git-dir='+GFDL_BASE_DIR+'/.git', '--work-tree='+GFDL_BASE_DIR) - git_test = codedir_git.log('-1', '--format="%H"').stdout + git_test = check_for_sh_stdout(codedir_git.log('-1', '--format="%H"')) baked_git_fn = git.bake('--git-dir='+dir_in+'/.git', '--work-tree='+dir_in) - return baked_git_fn \ No newline at end of file + return baked_git_fn + +def check_for_sh_stdout(input_exp): + """Versions of sh>2.* have started returning str types rather than a sh.RunningCommand type. To distinguish these possibilites, this function looks at the output of a sh expression, and asks for stdout and decodes it only if the type is a sh.RunningCommand.""" + + if type(input_exp)==sh.RunningCommand: + input_exp=input_exp.stdout.decode('utf8') + + return input_exp \ No newline at end of file diff --git a/src/extra/python/isca/templates/mkmf.template.dt2 b/src/extra/python/isca/templates/mkmf.template.dt2 new file mode 100644 index 000000000..2dc8b207c --- /dev/null +++ b/src/extra/python/isca/templates/mkmf.template.dt2 @@ -0,0 +1,28 @@ +# template for the Intel fortran compiler +# typical use with mkmf +# mkmf -t template.ifc -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include +CPPFLAGS = -I/usr/local/include +NETCDF_LIBS = `nf-config --fflags --flibs` + +# FFLAGS: +# -fpp: Use the fortran preprocessor +# -stack_temps: Put temporary runtime arrays on the stack, not heap. +# -safe_cray_ptr: Cray pointers don't alias other variables. +# -ftz: Denormal numbers are flushed to zero. +# -assume byterecl: Specifies the units for the OPEN statement as bytes. +# -shared-intel: Load intel libraries dynamically +# -i4: 4 byte integers +# -r8: 8 byte reals +# -g: Generate symbolic debugging info in code +# -O2: Level 2 speed optimisations +# -diag-disable 6843: +# This suppresses the warning: `warning #6843: A dummy argument with an explicit INTENT(OUT) declaration is not given an explicit value.` of which +# there are a lot of instances in the GFDL codebase. +FFLAGS = $(CPPFLAGS) -fpp -stack_temps -safe_cray_ptr -ftz -assume byterecl -shared-intel -i4 -r8 -g -O2 -diag-disable 6843 -mcmodel large +#FFLAGS = $(CPPFLAGS) -fltconsistency -stack_temps -safe_cray_ptr -ftz -shared-intel -assume byterecl -g -O0 -i4 -r8 -check -warn -warn noerrors -debug variable_locations -inline_debug_info -traceback +FC = $(F90) $(NETCDF_LIBS) +LD = $(F90) $(NETCDF_LIBS) +#CC = mpicc + +LDFLAGS = -lnetcdff -lnetcdf -lmpi -shared-intel +CFLAGS = -D__IFC diff --git a/src/extra/python/isca/templates/mkmf.template.maths2 b/src/extra/python/isca/templates/mkmf.template.maths2 new file mode 100755 index 000000000..fa6151185 --- /dev/null +++ b/src/extra/python/isca/templates/mkmf.template.maths2 @@ -0,0 +1,28 @@ +# template for the Intel fortran compiler +# typical use with mkmf +# mkmf -t template.ifc -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include +CPPFLAGS = `nc-config --cflags` +NETCDF_LIBS = `nc-config --libs` + +# FFLAGS: +# -fpp: Use the fortran preprocessor +# -stack_temps: Put temporary runtime arrays on the stack, not heap. +# -safe_cray_ptr: Cray pointers don't alias other variables. +# -ftz: Denormal numbers are flushed to zero. +# -assume byterecl: Specifies the units for the OPEN statement as bytes. +# -shared-intel: Load intel libraries dynamically +# -i4: 4 byte integers +# -r8: 8 byte reals +# -g: Generate symbolic debugging info in code +# -O2: Level 2 speed optimisations +# -diag-disable 6843: +# This suppresses the warning: `warning #6843: A dummy argument with an explicit INTENT(OUT) declaration is not given an explicit value.` of which +# there are a lot of instances in the GFDL codebase. +FFLAGS = $(CPPFLAGS) -fpp -stack_temps -safe_cray_ptr -ftz -assume byterecl -shared-intel -i4 -r8 -g -O2 -diag-disable 6843 -mcmodel large +#FFLAGS = $(CPPFLAGS) -fltconsistency -stack_temps -safe_cray_ptr -ftz -shared-intel -assume byterecl -g -O0 -i4 -r8 -check -warn -warn noerrors -debug variable_locations -inline_debug_info -traceback +FC = $(F90) +LD = $(F90) $(NETCDF_LIBS) +#CC = mpicc + +LDFLAGS = -lnetcdff -lnetcdf -lmpi -shared-intel -lhdf5_hl -lhdf5 -lm -lz -lsz -lbz2 -lxml2 -lcurl +CFLAGS = -D__IFC diff --git a/src/extra/python/isca/templates/mkmf.template.ubuntu_conda b/src/extra/python/isca/templates/mkmf.template.ubuntu_conda new file mode 100755 index 000000000..bd3dd5a83 --- /dev/null +++ b/src/extra/python/isca/templates/mkmf.template.ubuntu_conda @@ -0,0 +1,28 @@ +# template for the gfortran compiler +# typical use with mkmf +# mkmf -t template.ifc -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include +CPPFLAGS = `nc-config --cflags` +NC_INC=`nc-config --fflags` +NC_LIB=`nc-config --flibs` + +# FFLAGS: +# -cpp: Use the fortran preprocessor +# -ffree-line-length-none -fno-range-check: Allow arbitrarily long lines +# -fcray-pointer: Cray pointers don't alias other variables. +# -ftz: Denormal numbers are flushed to zero. +# -assume byterecl: Specifies the units for the OPEN statement as bytes. +# -shared-intel: Load intel libraries dynamically +# -i4: 4 byte integers +# -fdefault-real-8: 8 byte reals (compatability for some parts of GFDL code) +# -fdefault-double-8: 8 byte doubles (compat. with RRTM) +# -O2: Level 2 speed optimisations + +FFLAGS = $(CPPFLAGS) $(NC_LIB) -cpp -fcray-pointer \ + -O2 -ffree-line-length-none -fno-range-check \ + -fdefault-real-8 -fdefault-double-8 -fallow-invalid-boz -fallow-argument-mismatch + +FC = $(F90) +LD = $(F90) + +LDFLAGS = -lnetcdff -lnetcdf -lmpi +CFLAGS = -D__IFC diff --git a/src/extra/python/requirements.txt b/src/extra/python/requirements.txt index e2c9a6499..722b8d75b 100644 --- a/src/extra/python/requirements.txt +++ b/src/extra/python/requirements.txt @@ -1,7 +1,7 @@ sh jinja2 -git+git://github.com/marshallward/f90nml.git#egg=f90nml +f90nml numpy pandas xarray -tqdm \ No newline at end of file +tqdm diff --git a/src/extra/python/scripts/calendar_calc.py b/src/extra/python/scripts/calendar_calc.py index 2c40f6673..ac3aac37e 100644 --- a/src/extra/python/scripts/calendar_calc.py +++ b/src/extra/python/scripts/calendar_calc.py @@ -1,4 +1,4 @@ -from cftime import utime +import cftime from datetime import datetime from cmip_time import FakeDT import numpy as np @@ -8,9 +8,11 @@ def day_number_to_datetime_array(time_in, calendar_type, units_in): - cdftime = utime(units_in, calendar = calendar_type) + # cdftime = utime(units_in, calendar = calendar_type) - date_out = cdftime.num2date(time_in) + # date_out = cdftime.num2date(time_in) + + date_out = cftime.num2date(time_in, units_in, calendar=calendar_type) return date_out diff --git a/src/extra/python/scripts/create_timeseries.py b/src/extra/python/scripts/create_timeseries.py index 94a4a3998..b18d241d5 100644 --- a/src/extra/python/scripts/create_timeseries.py +++ b/src/extra/python/scripts/create_timeseries.py @@ -107,7 +107,11 @@ def create_time_arr(num_years,is_climatology,time_spacing): return time_arr,day_number,ntime,time_units,time_bounds -def output_to_file(data,lats,lons,latbs,lonbs,p_full,p_half,time_arr,time_units,file_name,variable_name,number_dict, time_bounds=None): +def output_multiple_variables_to_file(data_dict,lats,lons,latbs,lonbs,p_full,p_half,time_arr,time_units,file_name,number_dict, time_bounds=None): + """Default is to accept multiple data variables to put in the file. + Input format in data_dict = {variable_name:variable_array}. + Currently only accepts all 2D fields or all 3D fields. + Could be updated in future to accept a mix.""" output_file = Dataset(file_name, 'w', format='NETCDF3_CLASSIC') @@ -116,6 +120,10 @@ def output_to_file(data,lats,lons,latbs,lonbs,p_full,p_half,time_arr,time_units, else: is_thd=True + if time_arr is None: + add_time = False + else: + add_time = True lat = output_file.createDimension('lat', number_dict['nlat']) lon = output_file.createDimension('lon', number_dict['nlon']) @@ -137,7 +145,8 @@ def output_to_file(data,lats,lons,latbs,lonbs,p_full,p_half,time_arr,time_units, pfull = output_file.createDimension('pfull', number_dict['npfull']) phalf = output_file.createDimension('phalf', number_dict['nphalf']) - time = output_file.createDimension('time', 0) #s Key point is to have the length of the time axis 0, or 'unlimited'. This seems necessary to get the code to run properly. + if add_time: + time = output_file.createDimension('time', 0) #s Key point is to have the length of the time axis 0, or 'unlimited'. This seems necessary to get the code to run properly. latitudes = output_file.createVariable('lat','d',('lat',)) longitudes = output_file.createVariable('lon','d',('lon',)) @@ -146,7 +155,8 @@ def output_to_file(data,lats,lons,latbs,lonbs,p_full,p_half,time_arr,time_units, pfulls = output_file.createVariable('pfull','d',('pfull',)) phalfs = output_file.createVariable('phalf','d',('phalf',)) - times = output_file.createVariable('time','d',('time',)) + if add_time: + times = output_file.createVariable('time','d',('time',)) latitudes.units = 'degrees_N'.encode('utf-8') latitudes.cartesian_axis = 'Y' @@ -179,11 +189,11 @@ def output_to_file(data,lats,lons,latbs,lonbs,p_full,p_half,time_arr,time_units, phalfs.positive = 'down' phalfs.long_name = 'half pressure level' - - times.units = time_units - times.calendar = 'THIRTY_DAY_MONTHS' - times.calendar_type = 'THIRTY_DAY_MONTHS' - times.cartesian_axis = 'T' + if add_time: + times.units = time_units + times.calendar = 'THIRTY_DAY_MONTHS' + times.calendar_type = 'THIRTY_DAY_MONTHS' + times.cartesian_axis = 'T' if time_bounds is not None: @@ -198,12 +208,6 @@ def output_to_file(data,lats,lons,latbs,lonbs,p_full,p_half,time_arr,time_units, times.bounds = 'time_bounds' - - if is_thd: - output_array_netcdf = output_file.createVariable(variable_name,'f4',('time','pfull', 'lat','lon',)) - else: - output_array_netcdf = output_file.createVariable(variable_name,'f4',('time','lat','lon',)) - latitudes[:] = lats longitudes[:] = lons @@ -216,14 +220,34 @@ def output_to_file(data,lats,lons,latbs,lonbs,p_full,p_half,time_arr,time_units, pfulls[:] = p_full phalfs[:] = p_half - if type(time_arr[0])!=np.float64 and type(time_arr[0])!=np.int64 : - times[:] = date2num(time_arr,units='days since 0001-01-01 00:00:00.0',calendar='360_day') - else: - times[:] = time_arr - - output_array_netcdf[:] = data + if add_time: + if type(time_arr[0])!=np.float64 and type(time_arr[0])!=np.int64 : + times[:] = date2num(time_arr,units='days since 0001-01-01 00:00:00.0',calendar='360_day') + else: + times[:] = time_arr + + for variable_name in data_dict.keys(): + if is_thd: + if add_time: + three_d_dims = ('time','pfull', 'lat','lon',) + else: + three_d_dims = ('pfull', 'lat','lon',) + + output_array_netcdf = output_file.createVariable(variable_name,'f4',three_d_dims) + else: + if add_time: + two_d_dims = ('time','lat','lon',) + else: + two_d_dims = ('lat','lon',) + output_array_netcdf = output_file.createVariable(variable_name,'f4',two_d_dims) + + output_array_netcdf[:] = data_dict[variable_name] output_file.close() +def output_to_file(data,lats,lons,latbs,lonbs,p_full,p_half,time_arr,time_units,file_name,variable_name,number_dict, time_bounds=None): + """Special interface for script wanting to output 1 variable only.""" + data_dict_to_send = {variable_name:data} + output_multiple_variables_to_file(data_dict_to_send,lats,lons,latbs,lonbs,p_full,p_half,time_arr,time_units,file_name,number_dict,time_bounds=time_bounds) diff --git a/src/extra/python/scripts/find_namelists_to_check.py b/src/extra/python/scripts/find_namelists_to_check.py new file mode 100644 index 000000000..f13956ada --- /dev/null +++ b/src/extra/python/scripts/find_namelists_to_check.py @@ -0,0 +1,88 @@ +import subprocess +import os +import glob +from pathlib import Path +import pdb + +#A script to find the fortran files within Isca's src directory +#that include namelists, and to check if namelist checking is done. + +#find the location of the source code +GFDL_BASE = os.environ['GFDL_BASE'] + +#setup some output dictionaries and lists +fortran_file_dict = {} +includes_namelist_dict = {} +includes_check_namelist_dict = {} +n_check_namelist_dict = {} +if_def_internal_nml_dict={} + +files_with_namelists = [] +namelists_to_flag = [] +namelists_to_flag_possible = [] + + +#find ALL of the fortran files within GFDL_BASE/src directory +for path in Path(f'{GFDL_BASE}/src/').rglob('*.*90'): + #exclude files with ._ at the start + if path.name[0:2]!='._': + #add all the remaining files to a dictionary + fortran_file_dict[path.name] = path + +#go through each file and check if it contains a namelist, and if it does namelist checking +for file_name in fortran_file_dict.keys(): + file_path = fortran_file_dict[file_name] + + #initialise some of the checking variables + namelist_in_file=False + check_namelist_in_file=False + number_of_checks=0 + if_def_internal_nml_in_file=False + #open each of the fortran files + with open(file_path, 'r') as read_obj: + for line in read_obj: + #check if it contains a namelist + if 'namelist /' in line and not namelist_in_file: + namelist_in_file=True + # does it contain the check_nml_error command? + if 'check_nml_error' in line and not check_namelist_in_file: + check_namelist_in_file=True + # count how many times this string is mentioned + if 'check_nml_error' in line: + number_of_checks=number_of_checks+1 + #check if there's more than one type of namelist reading available + if '#ifdef INTERNAL_FILE_NML' in line and not if_def_internal_nml_in_file: + if_def_internal_nml_in_file=True + + #make a list of those files that do have a namelist + if namelist_in_file: + files_with_namelists.append(file_name) + + #make a list of those files that do have a namelist but don't do checking + if namelist_in_file and not check_namelist_in_file: + namelists_to_flag.append(file_name) + + #making a list of files that have namelists, that read them in more than one way, and have fewer than 3 mentions of check_nml_error. This is to catch cases where there is some namelist checking taking place, but it's not on all the methods of namelist reading. + if namelist_in_file and if_def_internal_nml_in_file and number_of_checks<3: + namelists_to_flag_possible.append(file_name) + + #keep a record of the files that include a namelist + includes_namelist_dict[file_name]=namelist_in_file + + #keep a record of the files that do and don't do namelist checking + includes_check_namelist_dict[file_name]=check_namelist_in_file + + #keep a record of the number of checks taking place + n_check_namelist_dict[file_name] = number_of_checks + +#create a list of files that appear in namelists_to_flag_possible +list_of_filepaths_to_check = [str(fortran_file_dict[path]) for path in namelists_to_flag_possible] + +#print the number of checks +print([n_check_namelist_dict[path] for path in namelists_to_flag_possible]) + +#print the list of files +print(namelists_to_flag_possible) + +#print their directories +print(list_of_filepaths_to_check) \ No newline at end of file diff --git a/src/extra/python/scripts/remove_certain_restart_and_data_files.py b/src/extra/python/scripts/remove_certain_restart_and_data_files.py index 98d658a95..582a05c9c 100644 --- a/src/extra/python/scripts/remove_certain_restart_and_data_files.py +++ b/src/extra/python/scripts/remove_certain_restart_and_data_files.py @@ -1,6 +1,7 @@ import sh import os import pdb +from glob import glob P = os.path.join @@ -12,11 +13,15 @@ def __init__(self, basedir, workdir, datadir, exp_name): self.expname = exp_name -def create_exp_object(exp_name): +def create_exp_object(exp_name, data_directory=None): + + if data_directory is None: + datadir = os.environ['GFDL_DATA'] + else: + datadir = data_directory - basedir = os.environ['GFDL_BASE'] workdir = os.environ['GFDL_WORK'] - datadir = os.environ['GFDL_DATA'] + basedir = os.environ['GFDL_BASE'] expname = '/'+exp_name+'/' exp_object = temporary_exp_object(basedir, workdir, datadir, exp_name) @@ -24,34 +29,42 @@ def create_exp_object(exp_name): return exp_object -def keep_only_certain_restart_files(exp_object, max_num_files, interval=12): +# def keep_only_certain_restart_files(exp_object, max_num_files, interval=12): - # sh.ls(sh.glob(P(self.workdir,'restarts','res_*.cpio'))) #TODO get max_num_files calculated in line, rather than a variable to pass. +# # sh.ls(sh.glob(P(self.workdir,'restarts','res_*.cpio'))) #TODO get max_num_files calculated in line, rather than a variable to pass. - #First defines a list of ALL the restart file numbers - files_to_remove=list(range(0,max_num_files)) +# #First defines a list of ALL the restart file numbers +# files_to_remove=list(range(0,max_num_files)) - #Then defines a list of the ones we want to KEEP - files_to_keep =list(range(0,max_num_files,interval)) +# #Then defines a list of the ones we want to KEEP +# files_to_keep =list(range(0,max_num_files,interval)) - #Then we remove the files we want to keep from the list of all files, giving a list of those we wish to remove - for x in files_to_keep: - files_to_remove.remove(x) +# #Then we remove the files we want to keep from the list of all files, giving a list of those we wish to remove +# for x in files_to_keep: +# files_to_remove.remove(x) - #Then we remove them. - for entry in files_to_remove: - try: - sh.rm(P(exp_object.workdir,exp_object.expname,'restarts','res_'+str(entry)+'.cpio')) -# print P(exp_object.workdir,exp_object.expname,'restarts','res_'+str(entry)+'.cpio') +# #Then we remove them. +# for entry in files_to_remove: +# try: +# sh.rm(P(exp_object.workdir,exp_object.expname,'restarts','res_'+str(entry)+'.cpio')) +# # print P(exp_object.workdir,exp_object.expname,'restarts','res_'+str(entry)+'.cpio') - except sh.ErrorReturnCode_1: - pass -# print 'Tried to remove some restart files, but number '+str(entry)+' does not exist' +# except sh.ErrorReturnCode_1: +# pass +# # print 'Tried to remove some restart files, but number '+str(entry)+' does not exist' -def keep_only_certain_restart_files_data_dir(exp_object, max_num_files, interval=12): +def keep_only_certain_restart_files_data_dir(exp_object, max_num_files=None, interval=12): # sh.ls(sh.glob(P(self.workdir,'restarts','res_*.cpio'))) #TODO get max_num_files calculated in line, rather than a variable to pass. + if max_num_files is None: + month_list = glob(P(exp_object.datadir,exp_object.expname, 'restarts')+'/res*.tar.gz') + if len(month_list)==0: + return + else: + final_month = month_list[-1].split('/res') + max_num_files = int(final_month[-1].split('.tar.gz')[0]) + #First defines a list of ALL the restart file numbers files_to_remove=list(range(0,max_num_files)) @@ -62,13 +75,27 @@ def keep_only_certain_restart_files_data_dir(exp_object, max_num_files, interval for x in files_to_keep: files_to_remove.remove(x) + first_to_be_removed = True + number_removed = 0 + number_not_removed = 0 #Then we remove them. - for entry in files_to_remove: + for entry in files_to_remove[1:-1]: try: - sh.rm(P(exp_object.datadir,exp_object.expname,'run%03d' % entry,'INPUT','res')) -# print 'would be removing ' + P(exp_object.datadir,exp_object.expname,'run'+str(entry),'INPUT','res') + file_to_remove = P(exp_object.datadir,exp_object.expname, 'restarts', 'res%04d.tar.gz' % entry) + if os.path.isfile(file_to_remove) and first_to_be_removed: + first_to_be_removed=False + number_not_removed+=1 + # print('would have removed '+file_to_remove+' but wanted to make sure not to delete the first restart') + else: + sh.rm(file_to_remove) + number_removed+=1 + # print('have removed ' + file_to_remove) except sh.ErrorReturnCode_1: + number_not_removed+=1 + # print('could not remove ' + file_to_remove) pass + print(P(exp_object.datadir,exp_object.expname), 'number removed '+str(number_removed), 'number not removed '+str(number_not_removed)) + # print 'Tried to remove some restart files, but number '+str(entry)+' does not exist' def keep_only_certain_daily_data_uninterp(exp_object, max_num_files, interval=None, file_name = 'atmos_daily.nc'): @@ -88,8 +115,8 @@ def keep_only_certain_daily_data_uninterp(exp_object, max_num_files, interval=No #Then we remove them. for entry in files_to_remove: try: - sh.rm(P(exp_object.datadir,exp_object.expname,'run%03d' % entry,file_name)) - print(('Removed '+P(exp_object.datadir,exp_object.expname,'run%03d' % entry,file_name))) + sh.rm(P(exp_object.datadir,exp_object.expname,'run%04d' % entry,file_name)) + print(('Removed '+P(exp_object.datadir,exp_object.expname,'run%04d' % entry,file_name))) except sh.ErrorReturnCode_1: pass # print 'Tried to remove some atmos_daily files, but number '+str(entry)+' does not exist' @@ -98,36 +125,18 @@ def keep_only_certain_daily_data_uninterp(exp_object, max_num_files, interval=No if __name__=="__main__": - max_num_files_input = 325 + max_num_files_input = None -# exp_name_list=['simple_continents_post_princeton_qflux_anoms_'+str(x) for x in range(31,32)] - -# exp_name_list=['aquaplanet_qflux_anoms_'+str(x) for x in [12,18,23,32,8]] - -# exp_name_list = ['simple_continents_post_princeton_qflux_control_1','simple_continents_post_princeton_fixed_sst_1', 'simple_continents_post_princeton_qflux_control_nod_1', 'simple_continents_post_princeton_qflux_control_scf_1'] -# -# exp_name_list = ['annual_mean_ice_princeton_qflux_control_matrix_qflux_2017_code_1', 'annual_mean_ice_post_princeton_fixed_sst_1', 'annual_mean_ice_princeton_fixed_sst_1'] -# -# exp_name_list.extend(['annual_mean_ice_post_princeton_fixed_sst_el_nino_1']) - -# exp_name_list = ['simple_continents_post_princeton_qflux_control_1'] - -# exp_name_list = ['annual_mean_ice_princeton_qflux_control_1']#, 'annual_mean_ice_post_princeton_qflux_control_1'] - -# exp_name_list = ['annual_mean_ice_post_princeton_fixed_sst_TEST_1', 'annual_mean_ice_princeton_qflux_control_matrix_qflux_1'] - -# exp_name_list.extend(['simple_continents_post_princeton_fixed_sst_1']) - -# exp_name_list = ['giant_drag_exp_chai_values_without_dc_bug_latest_1'] -# exp_name_list = ['aquaplanet_qflux_control_1'] + # exp_name_list = [''] + exp_name_list = glob('/disca/share/sit204/data_isca_from_gv5/frierson_post_soc_fix_*/') - exp_name_list = ['giant_drag_exp_chai_values_with_dc_bug_latest_start_to_finish_1', 'giant_drag_exp_chai_values_without_dc_bug_latest_start_to_finish_1'] for exp_name_input in exp_name_list: - temp_obj = create_exp_object(exp_name_input) - keep_only_certain_restart_files(temp_obj, max_num_files_input) + print('Percentage progress through list:'+str(exp_name_list.index(exp_name_input)/len(exp_name_list))) + temp_obj = create_exp_object(exp_name_input, data_directory='/disca/share/sit204/data_from_isca_cpu/') + # keep_only_certain_restart_files(temp_obj, max_num_files_input) keep_only_certain_restart_files_data_dir(temp_obj, max_num_files_input) - keep_only_certain_daily_data_uninterp(temp_obj, max_num_files_input, file_name = 'fms_moist.x') + # keep_only_certain_daily_data_uninterp(temp_obj, max_num_files_input, file_name = 'fms_moist.x') # keep_only_certain_daily_data_uninterp(temp_obj, max_num_files_input) \ No newline at end of file diff --git a/src/extra/python/scripts/shallow_water_init_conds.py b/src/extra/python/scripts/shallow_water_init_conds.py new file mode 100644 index 000000000..2f8bca068 --- /dev/null +++ b/src/extra/python/scripts/shallow_water_init_conds.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*-s +from typing import NoReturn +import numpy as np +import pdb +import create_timeseries as cts +import xarray as xar +import gauss_grid as gg +import matplotlib.pyplot as plt +import windspharm as wsp +import pdb + +def convert_to_vor_div(u_in, v_in, lat_arr, planet_radius): + """convert spherical polar velocities to vor and div""" + + uwnd, uwnd_info = wsp.tools.prep_data(u_in, 'yx') + vwnd, vwnd_info = wsp.tools.prep_data(v_in, 'yx') + + # It is also required that the latitude dimension is north-to-south. Again the + # bundled tools make this easy. + lat_1d_ordered, uwnd, vwnd = wsp.tools.order_latdim(lat_arr[:,0], uwnd, vwnd) + + # Create a VectorWind instance to handle the computation of streamfunction and + # velocity potential. + w = wsp.standard.VectorWind(uwnd, vwnd, rsphere=planet_radius, gridtype='gaussian') + + # Compute the streamfunction and velocity potential. Also use the bundled + # tools to re-shape the outputs to the 4D shape of the wind components as they + # were read off files. + vor = w.vorticity() + div = w.divergence() + # sf, vp = w.sfvp() + vor = wsp.tools.recover_data(vor, uwnd_info) + div = wsp.tools.recover_data(div, uwnd_info) + + return vor[::-1,:], div[::-1,:] #need to reverse latitude reordering + +def set_u_v_height_field(lon_in, lat_in, lonb_in, latb_in, epsilon, alpha, beta, m, r_0, planet_radius, northern_hemisphere=True): + """Configure an initial condition for u, v and h given some + balance condition. Use parameters and gradient-wind balance for Saturn + from 10.1016/j.icarus.2017.06.006""" + + deformation_scale = 3200e3 #p62 of Rostami et al 2017 + f_0 = 3.2e-4 + timescale = (f_0)**-1 + velocity_scale = deformation_scale/timescale + + lat_rad_2d = np.deg2rad(lat_in) + lon_rad_2d = np.deg2rad(lon_in) + + if northern_hemisphere: + r_array = (planet_radius * (np.pi/2. - lat_rad_2d))/deformation_scale #non-dim + else: + r_array = (planet_radius * (np.pi/2. + lat_rad_2d))/deformation_scale #non-dim + + v = np.zeros_like(lat_in) + u = epsilon * ((r_array - r_0)**alpha)* np.exp(-m*((r_array-r_0)**beta)) + + v_si_units = v * velocity_scale + u_si_units = u * velocity_scale + + if northern_hemisphere: + grad_geopot = ((u_si_units**2)/(r_array* deformation_scale)) + (f_0*np.sin(lat_rad_2d)*u_si_units) + else: + #I've changed the sign of the coriolis term here. Clearly this isn't really happening, but in this funny radial coordinate system the sign of u would change for the opposite hemisphere, thus necessitating the sign change. + grad_geopot = ((u_si_units**2)/(r_array* deformation_scale)) - (f_0*np.sin(lat_rad_2d)*u_si_units) + + geopotential = np.zeros_like(grad_geopot) + + if northern_hemisphere: + for lat_idx in range(1, len(lat_rad_2d[:,0])): + geopotential[lat_idx,:] = geopotential[lat_idx-1,:] + 0.5*(grad_geopot[lat_idx-1,:]+grad_geopot[lat_idx,:])*(r_array[lat_idx]-r_array[lat_idx-1]) + else: + r_array_opposite = r_array[::-1,:] + grad_geopot_opposite = grad_geopot[::-1,:] + for lat_idx in range(1, len(lat_rad_2d[:,0])): + geopotential[lat_idx,:] = geopotential[lat_idx-1,:] + 0.5*(grad_geopot_opposite[lat_idx-1,:]+grad_geopot_opposite[lat_idx,:])*(r_array_opposite[lat_idx]-r_array_opposite[lat_idx-1]) + + geopotential = geopotential[::-1,:] + + #we want to pass a geopotential field that has an area-mean of zero. This is because we want to preserve the mean geopotential that the model sets as its h_0 parameter. + + delta_lat_arr = np.diff(latb_in, axis=0)[:,0:-1] + + area_array = np.cos(np.deg2rad(lat_in))*np.deg2rad(delta_lat_arr) + + area_av_geopot = np.sum(geopotential*area_array)/np.sum(area_array) + + geopotential_av_removed = geopotential-area_av_geopot + + area_av_final = np.sum(geopotential_av_removed*area_array)/np.sum(area_array) + + print(f'old mean = {area_av_geopot}, final area_av geopot = {area_av_final}') + + geopotential_si_units = geopotential_av_removed * deformation_scale + + h_0 = (deformation_scale*f_0)**2. + + return u_si_units, v_si_units, geopotential_si_units, h_0, grad_geopot + +nlat=128 +nlon=256 + +latitudes, latitude_bounds_2 = gg.gaussian_latitudes(int(nlat/2)) +latitude_bounds = [latitude_bound[0] for latitude_bound in latitude_bounds_2] + [latitude_bounds_2[-1][1]] + +longitudes = np.linspace(0., 360., nlon, endpoint=False) +delta_lon = longitudes[1]-longitudes[0] +longitude_bounds = [lon_val-(0.5*delta_lon) for lon_val in longitudes] + [np.max(longitudes)+(0.5*delta_lon)] +time_arr_adj=None + +lon_array_2d, lat_array_2d = np.meshgrid(longitudes, latitudes) +lonb_array_2d, latb_array_2d = np.meshgrid(longitude_bounds, latitude_bounds) + +#Note that in the following we're making the initial condition symmetric about the equator. This is because if you only set the initial conditions in the northern hemisphere then you end up needing a very large set of latitudinal functions to get that level of asymmetry, and the code gets very upset when translating that to a finite spectral representation. Making it symmetric gets rid of this problem, at least to some extent. + +epsilon = 0.15*2. +alpha = 0.42 +beta = 1.3 +r_0 = 0. +m_param = 1. +planet_radius = 55000e3 + +u_array_vortex, v_array_vortex, height_array_vortex, h_0, grad_geopot_vortex = set_u_v_height_field(lon_array_2d, lat_array_2d,lonb_array_2d, latb_array_2d, epsilon, alpha, beta, m_param, r_0, planet_radius) + +u_array_vortex_sp, v_array_vortex_sp, height_array_vortex_sp, h_0_sp, grad_geopot_vortex_sp = set_u_v_height_field(lon_array_2d, lat_array_2d,lonb_array_2d, latb_array_2d, epsilon, alpha, beta, m_param, r_0, planet_radius, northern_hemisphere=False) + +epsilon = 0.08 +alpha = 0. +beta = 2. +r_0 = 3.37 +m_param = 3. +planet_radius = 55000e3 + +u_array_jet, v_array_jet, height_array_jet, h_0, grad_geopot_jet = set_u_v_height_field(lon_array_2d, lat_array_2d,lonb_array_2d, latb_array_2d, epsilon, alpha, beta, m_param, r_0, planet_radius) + +u_array_jet_sp, v_array_jet_sp, height_array_jet_sp, h_0_sp, grad_geopot_jet_sp = set_u_v_height_field(lon_array_2d, lat_array_2d,lonb_array_2d, latb_array_2d, epsilon, alpha, beta, m_param, r_0, planet_radius, northern_hemisphere=False) + + +u_array_total = u_array_vortex+u_array_vortex_sp + u_array_jet+u_array_jet_sp +v_array_total = v_array_vortex+v_array_vortex_sp + v_array_jet+v_array_jet_sp +height_array_total = height_array_vortex+height_array_vortex_sp + height_array_jet+height_array_jet_sp +grad_geopot_total = grad_geopot_vortex + grad_geopot_vortex_sp + grad_geopot_jet + grad_geopot_jet_sp + +vor_array, div_array = convert_to_vor_div(u_array_total, v_array_total, height_array_total, planet_radius) + + +p_full=None +p_half=None + +npfull=None +nphalf=None + +#Output it to a netcdf file. + +file_name='rostami_t85_jet_and_vortex_mk7_gg.nc' + + +number_dict={} +number_dict['nlat']=nlat +number_dict['nlon']=nlon +number_dict['nlatb']=nlat+1 +number_dict['nlonb']=nlon+1 +number_dict['npfull']=npfull +number_dict['nphalf']=nphalf +number_dict['ntime']=None + +data_dict = { + 'vor': vor_array, + 'height': height_array_total, + 'div': div_array, + 'ucomp': u_array_total, + 'vcomp': v_array_total, + 'grad_geopot': grad_geopot_total +} + + +time_units=None + +cts.output_multiple_variables_to_file(data_dict,latitudes,longitudes,latitude_bounds,longitude_bounds,p_full,p_half,time_arr_adj,time_units,file_name,number_dict) + +print(f'Must set h_0 parameter in code to be {h_0}') + + + diff --git a/src/shared/astronomy/astronomy.f90 b/src/shared/astronomy/astronomy.f90 index b5181b56d..e3e88854e 100644 --- a/src/shared/astronomy/astronomy.f90 +++ b/src/shared/astronomy/astronomy.f90 @@ -296,6 +296,7 @@ subroutine astronomy_init (latb, lonb) !----------------------------------------------------------------------- #ifdef INTERNAL_FILE_NML read (input_nml_file, astronomy_nml, iostat=io) + ierr = check_nml_error(io,'astronomy_nml') #else if ( file_exist('input.nml')) then unit = open_namelist_file ( ) diff --git a/src/shared/axis_utils/axis_utils.F90 b/src/shared/axis_utils/axis_utils.F90 index c83e35be9..461029193 100644 --- a/src/shared/axis_utils/axis_utils.F90 +++ b/src/shared/axis_utils/axis_utils.F90 @@ -854,6 +854,7 @@ program test !---reading namelist #ifdef INTERNAL_FILE_NML read (input_nml_file, test_axis_utils_nml, iostat=io) + ierr = check_nml_error(io,'test_axis_utils_nml') ! also initializes nml error codes #else if(file_exist('input.nml')) then unit = open_namelist_file() diff --git a/src/shared/constants/constants.F90 b/src/shared/constants/constants.F90 index 130d3c7f7..42ee900a5 100644 --- a/src/shared/constants/constants.F90 +++ b/src/shared/constants/constants.F90 @@ -58,16 +58,16 @@ module constants_mod ! ! acceleration due to gravity ! -! +! ! gas constant for dry air ! ! ! RDGAS / CP_AIR ! -! +! ! specific heat capacity of dry air at constant pressure ! -! +! ! specific heat capacity taken from McDougall (2002) "Potential Enthalpy ..." ! ! @@ -76,8 +76,8 @@ module constants_mod ! ! reciprocal of average density of sea water ! -! -! (kg/m^3)*(cal/kg/deg C)(joules/cal) = (joules/m^3/deg C) +! +! (kg/m^3)*(J/kg/K) = (J/m^3/K) ! real, public, parameter :: EARTH_GRAV = 9.80 @@ -90,7 +90,7 @@ module constants_mod real, public, parameter :: RHO_CP = RHO0*CP_OCEAN !------------ water vapor constants --------------- -! +! ! Humidity factor. Controls the humidity content of the atmosphere through ! the Saturation Vapour Pressure expression when using DO_SIMPLE. ! @@ -116,7 +116,7 @@ module constants_mod ! temp where fresh water freezes ! -real, public, parameter :: ES0 = 1.0 +real, public, parameter :: DEF_ES0 = 1.0 real, public, parameter :: RVGAS = 461.50 real, public, parameter :: CP_VAPOR = 4.0*RVGAS real, public, parameter :: DENS_H2O = 1000. @@ -264,9 +264,10 @@ module constants_mod real, public :: RDGAS = EARTH_RDGAS real, public :: KAPPA = EARTH_KAPPA real, public :: CP_AIR = EARTH_CP_AIR +real, public :: es0 = DEF_ES0 logical :: earthday_multiple = .false. -namelist/constants_nml/ radius, grav, omega, orbital_period, pstd, pstd_mks, rdgas, kappa, solar_const, earthday_multiple +namelist/constants_nml/ radius, grav, omega, orbital_period, pstd, pstd_mks, rdgas, kappa, solar_const, earthday_multiple, es0 !----------------------------------------------------------------------- ! version and tagname published @@ -311,7 +312,7 @@ subroutine constants_init else seconds_per_sol = abs(2*pi / (orbital_rate - omega)) endif - + CP_AIR = RDGAS/KAPPA constants_initialised = .true. @@ -352,4 +353,3 @@ end module constants_mod ! ! - diff --git a/src/shared/diag_manager/diag_table.F90 b/src/shared/diag_manager/diag_table.F90 index 1cb063bef..650ac020e 100644 --- a/src/shared/diag_manager/diag_table.F90 +++ b/src/shared/diag_manager/diag_table.F90 @@ -357,7 +357,7 @@ SUBROUTINE parse_diag_table(diag_subset, istat, err_msg) INTEGER, INTENT(out), OPTIONAL, TARGET :: istat CHARACTER(len=*), INTENT(out), OPTIONAL :: err_msg - INTEGER, PARAMETER :: DT_LINE_LENGTH = 256 + INTEGER, PARAMETER :: DT_LINE_LENGTH = 512 INTEGER :: stdlog_unit !< Fortran file unit number for the stdlog file. INTEGER :: record_len !< String length of the diag_table line read in. diff --git a/src/shared/horiz_interp/horiz_interp.F90 b/src/shared/horiz_interp/horiz_interp.F90 index 9a5263a05..a54aa34ca 100644 --- a/src/shared/horiz_interp/horiz_interp.F90 +++ b/src/shared/horiz_interp/horiz_interp.F90 @@ -1288,6 +1288,7 @@ program horiz_interp_test !--- read namelist #ifdef INTERNAL_FILE_NML read (input_nml_file, test_horiz_interp_nml, iostat=io) + ierr = check_nml_error(io, 'test_horiz_interp_nml') #else if (file_exist('input.nml')) then ierr=1 diff --git a/src/shared/horiz_interp/horiz_interp_spherical.F90 b/src/shared/horiz_interp/horiz_interp_spherical.F90 index 5c52909f7..6603650c8 100644 --- a/src/shared/horiz_interp/horiz_interp_spherical.F90 +++ b/src/shared/horiz_interp/horiz_interp_spherical.F90 @@ -104,6 +104,7 @@ subroutine horiz_interp_spherical_init call write_version_number (version, tagname) #ifdef INTERNAL_FILE_NML read (input_nml_file, horiz_interp_spherical_nml, iostat=io) + ierr = check_nml_error(io,'horiz_interp_spherical_nml') ! also initializes nml error codes #else if (file_exist('input.nml')) then unit = open_namelist_file ( ) diff --git a/src/shared/mpp/mpp.F90 b/src/shared/mpp/mpp.F90 index 0c808bac3..3f69032b1 100644 --- a/src/shared/mpp/mpp.F90 +++ b/src/shared/mpp/mpp.F90 @@ -1182,7 +1182,7 @@ module mpp_mod ! variables needed for subroutine read_input_nml (include/mpp_util.inc) ! ! parameter defining length of character variables - integer, parameter :: INPUT_STR_LENGTH = 256 + integer, parameter :: INPUT_STR_LENGTH = 512 ! public variable needed for reading input.nml from an internal file character(len=INPUT_STR_LENGTH), dimension(:), allocatable, public :: input_nml_file !*********************************************************************** diff --git a/src/shared/sat_vapor_pres/sat_vapor_pres.F90 b/src/shared/sat_vapor_pres/sat_vapor_pres.F90 index 1e1a6f3aa..f182831a6 100644 --- a/src/shared/sat_vapor_pres/sat_vapor_pres.F90 +++ b/src/shared/sat_vapor_pres/sat_vapor_pres.F90 @@ -2278,6 +2278,7 @@ subroutine sat_vapor_pres_init(err_msg) !---- read namelist input ---- #ifdef INTERNAL_FILE_NML read (input_nml_file, sat_vapor_pres_nml, iostat=io) + ierr = check_nml_error(io,'sat_vapor_pres_nml') #else if (file_exist('input.nml')) then unit = open_namelist_file ( ) diff --git a/src/shared/time_interp/time_interp.F90 b/src/shared/time_interp/time_interp.F90 index 94d7046db..442beb020 100644 --- a/src/shared/time_interp/time_interp.F90 +++ b/src/shared/time_interp/time_interp.F90 @@ -233,6 +233,7 @@ subroutine time_interp_init() #ifdef INTERNAL_FILE_NML read (input_nml_file, time_interp_nml, iostat=io) + ierr = check_nml_error (io, 'time_interp_nml') #else namelist_unit = open_namelist_file() ierr=1 diff --git a/src/shared/time_manager/get_cal_time.F90 b/src/shared/time_manager/get_cal_time.F90 index 912686a57..dc36d084f 100644 --- a/src/shared/time_manager/get_cal_time.F90 +++ b/src/shared/time_manager/get_cal_time.F90 @@ -188,6 +188,7 @@ function get_cal_time(time_increment, units, calendar, permit_calendar_conversio if(.not.module_is_initialized) then #ifdef INTERNAL_FILE_NML read (input_nml_file, get_cal_time_nml, iostat=io) + ierr = check_nml_error (io, 'get_cal_time_nml') #else namelist_unit = open_namelist_file() ierr=1 diff --git a/src/shared/time_manager/time_manager.F90 b/src/shared/time_manager/time_manager.F90 index 8d78b0ae8..6f7654f26 100644 --- a/src/shared/time_manager/time_manager.F90 +++ b/src/shared/time_manager/time_manager.F90 @@ -3479,6 +3479,7 @@ program test #ifdef INTERNAL_FILE_NML read (input_nml_file, test_nml, iostat=io) + ierr = check_nml_error (io, 'test_nml') #else nmlunit = open_namelist_file() ierr=1 diff --git a/src/shared/topography/gaussian_topog.F90 b/src/shared/topography/gaussian_topog.F90 index d76073a31..314563124 100644 --- a/src/shared/topography/gaussian_topog.F90 +++ b/src/shared/topography/gaussian_topog.F90 @@ -270,6 +270,7 @@ subroutine read_namelist #ifdef INTERNAL_FILE_NML read (input_nml_file, gaussian_topog_nml, iostat=io) + ierr = check_nml_error(io,'gaussian_topog_nml') #else if ( file_exist('input.nml')) then unit = open_namelist_file ( ) diff --git a/src/shared/topography/topography.F90 b/src/shared/topography/topography.F90 index cce81005b..156a5a50a 100644 --- a/src/shared/topography/topography.F90 +++ b/src/shared/topography/topography.F90 @@ -920,6 +920,7 @@ subroutine read_namelist #ifdef INTERNAL_FILE_NML read (input_nml_file, topography_nml, iostat=io) + ierr = check_nml_error(io,'topography_nml') #else if ( file_exist('input.nml')) then unit = open_namelist_file ( )